module Isomorfeus::Puppetmaster::Driver::PuppeteerDocument

Public Instance Methods

document_accept_alert(document, **options, &block) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 5
        def document_accept_alert(document, **options, &block)
          # TODO maybe wrap in mutex
          text =  options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
          @context.exec <<~JAVASCRIPT
            ModalText = #{text};
            AllPageHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
          JAVASCRIPT
          block.call
          sleep @reaction_timeout
          @context.eval 'ModalText'
        ensure
          matched = await <<~JAVASCRIPT
            LastResult = ModalTextMatched;
            ModalTextMatched = false;
            ModalText = null;
            AllPageHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
          JAVASCRIPT
          raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
        end
document_accept_confirm(document, **options, &block) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 25
        def document_accept_confirm(document, **options, &block)
          # TODO maybe wrap in mutex
          text =  options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
          @context.exec <<~JAVASCRIPT
            ModalText = #{text};
            AllPageHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
          JAVASCRIPT
          block.call
          sleep @reaction_timeout
          @context.eval 'ModalText'
        ensure
          matched = await <<~JAVASCRIPT
            LastResult = ModalTextMatched;
            ModalTextMatched = false;
            ModalText = null;
            AllPageHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
          JAVASCRIPT
          raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
        end
document_accept_leave_page(document, **options, &block) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 45
        def document_accept_leave_page(document, **options, &block)
          # TODO maybe wrap in mutex
          text =  options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
          @context.exec <<~JAVASCRIPT
            ModalText = #{text};
            AllPageHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
          JAVASCRIPT
          block.call
          sleep @reaction_timeout
          @context.eval 'ModalText'
        ensure
          matched = await <<~JAVASCRIPT
            LastResult = ModalTextMatched;
            ModalTextMatched = false;
            ModalText = null;
            AllPageHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
          JAVASCRIPT
          raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
        end
document_accept_prompt(document, **options, &block) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 65
        def document_accept_prompt(document, **options, &block)
          # TODO maybe wrap in mutex
          text =  options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
          @context.exec <<~JAVASCRIPT
            ModalText = #{text};
            AllPageHandles[#{document.handle}].on('dialog', DialogAcceptHandler);
          JAVASCRIPT
          block.call
          sleep @reaction_timeout
          @context.eval 'ModalText'
        ensure
          matched = await <<~JAVASCRIPT
            LastResult = ModalTextMatched;
            ModalTextMatched = false;
            ModalText = null;
            AllPageHandles[#{document.handle}].removeListener('dialog', DialogAcceptHandler);
          JAVASCRIPT
          raise Isomorfeus::Puppetmaster::NoModalError if options.has_key?(:text) && !matched
        end
document_all_text(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 85
def document_all_text(document)
  await("LastResult = AllPageHandles[#{document.handle}].evaluate(function(){ return document.documentElement.textContent; });")
end
document_body(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 89
        def document_body(document)
          node_data = await <<~JAVASCRIPT
            var element_handle = await AllPageHandles[#{document.handle}].$('body');
            if (element_handle) {
              var node_handle = RegisterElementHandle(element_handle);
              var tt = await AllElementHandles[node_handle].executionContext().evaluate((node) => {
                var name = node.nodeName;
                var tag = node.tagName.toLowerCase();
                return [name, tag, null, node.isContentEditable];
              }, AllElementHandles[node_handle]);
              LastResult = {handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]};
            }
          JAVASCRIPT
          if node_data
            node_data[:css_selector] = 'body'
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          end
        end
document_bring_to_front(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 108
def document_bring_to_front(document)
  await("await AllPageHandles[#{document.handle}].bringToFront();")
end
document_clear_authentication_credentials(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 112
def document_clear_authentication_credentials(document)
  await("AllPageHandles[#{document.handle}].authenticate(null);")
end
document_clear_cookies(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 116
        def document_clear_cookies(document)
          await <<~JAVASCRIPT
            var cookies = await AllPageHandles[#{document.handle}].cookies();
            cookies.forEach(async(cookie) => {await AllPageHandles[#{document.handle}].deleteCookie(cookie);});
          JAVASCRIPT
        end
document_clear_extra_headers(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 123
def document_clear_extra_headers(document)
  await ("AllPageHandles[#{document.handle}].setExtraHTTPHeaders({});")
end
document_clear_url_blacklist(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 127
        def document_clear_url_blacklist(document)
          await <<~JAVASCRIPT
            var cdp_session = await AllPageHandles[#{document.handle}].target().createCDPSession();
            await cdp_session.send('Network.setBlockedURLs', {urls: []});
            await cdp_session.detach();
          JAVASCRIPT
        end
document_click(document, x: nil, y: nil, modifiers: nil) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 135
        def document_click(document, x: nil, y: nil, modifiers: nil)
          # modifier_keys: :alt, :control, :meta, :shift
          # await "await  AllPageHandles[#{document.handle}].mouse.click(#{x},#{y},{button: 'left'});"
          # raise Isomorfeus::Pupppetmaster::InvalidActionError.new(:click) unless visible?
          modifiers = [modifiers] if modifiers.is_a?(Symbol)
          modifiers = [] unless modifiers
          modifiers = modifiers.map {|key| key.to_s.camelize(:lower) }
          await <<~JAVASCRIPT
            var response_event_occurred = false;
            var response_handler = function(event){ response_event_occurred = true; };
            var response_watcher = new Promise(function(resolve, reject){
              setTimeout(function(){
                if (!response_event_occurred) { resolve(true); } 
                else { setTimeout(function(){ resolve(true); }, #{@puppeteer_timeout}); }
                AllPageHandles[#{document.handle}].removeListener('response', response_handler);
              }, #{@puppeteer_reaction_timeout});
            });
            AllPageHandles[#{document.handle}].on('response', response_handler);
            var navigation_watcher = AllPageHandles[#{document.handle}].waitForNavigation();
            await AllPageHandles[#{document.handle}].evaluate(function(){ 
              var options = {button: 0, bubbles: true, cancelable: true};
              var node = window;
              var x = #{x ? x : 'null'};
              var y = #{y ? y : 'null'};
              var modifiers = #{modifiers};
              if (x && y) {
                options['clientX'] = x;
                options['clientY'] = y;
                var n = document.elementFromPoint(x, y);
                if (n) { node = n };
              }  
              if (modifiers.includes('meta')) { options['metaKey'] = true; }
              if (modifiers.includes('control')) { options['ctrlKey'] = true; }
              if (modifiers.includes('shift')) { options['shiftKey'] = true; }
              if (modifiers.includes('alt')) { options['altKey'] = true; }
              node.dispatchEvent(new MouseEvent('mousedown', options));
              node.dispatchEvent(new MouseEvent('mouseup', options));
              node.dispatchEvent(new MouseEvent('click', options));
            });
            await Promise.race([response_watcher, navigation_watcher]);
          JAVASCRIPT
        end
document_close(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 178
        def document_close(document)
          await <<~JAVASCRIPT
            await AllPageHandles[#{document.handle}].close();
            delete AllPageHandles[#{document.handle}];
            delete ConsoleMessages[#{document.handle}];
          JAVASCRIPT
        end
document_console(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 186
def document_console(document)
  messages = @context.exec "return ConsoleMessages[#{document.handle}]"
  messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
end
document_cookies(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 191
def document_cookies(document)
  result = await("LastResult = await AllPageHandles[#{document.handle}].cookies();")
  result_hash = {}
  result.each { |cookie| result_hash[cookie['name']] = Isomorfeus::Puppetmaster::Cookie.new(cookie) }
  result_hash
end
document_dismiss_confirm(document, **options, &block) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 198
        def document_dismiss_confirm(document, **options, &block)
          # TODO
          text =  options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
          @context.exec <<~JAVASCRIPT
            ModalText = #{text};
            AllPageHandles[#{document.handle}].on('dialog', DialogDismissHandler);
          JAVASCRIPT
          block.call
          sleep @reaction_timeout
          @context.eval 'ModalText'
        ensure
          matched = await <<~JAVASCRIPT
            LastResult = ModalTextMatched;
            ModalTextMatched = false;
            ModalText = null;
            AllPageHandles[#{document.handle}].removeListener('dialog', DialogDismissHandler);
          JAVASCRIPT
          raise Isomorfeus::Puppetmaster::ModalNotFound if options.has_key?(:text) && !matched
        end
document_dismiss_leave_page(document, **options, &block) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 218
        def document_dismiss_leave_page(document, **options, &block)
          # TODO
          text =  options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
          @context.exec <<~JAVASCRIPT
            ModalText = #{text};
            AllPageHandles[#{document.handle}].on('dialog', DialogDismissHandler);
          JAVASCRIPT
          block.call
          sleep @reaction_timeout
          @context.eval 'ModalText'
        ensure
          matched = await <<~JAVASCRIPT
            LastResult = ModalTextMatched;
            ModalTextMatched = false;
            ModalText = null;
            AllPageHandles[#{document.handle}].removeListener('dialog', DialogDismissHandler);
          JAVASCRIPT
          raise Isomorfeus::Puppetmaster::ModalNotFound if options.has_key?(:text) && !matched
        end
document_dismiss_prompt(document, **options, &block) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 238
        def document_dismiss_prompt(document, **options, &block)
          # TODO
          text =  options.has_key?(:text) ? "`#{options[:text]}`" : 'null'
          @context.exec <<~JAVASCRIPT
            ModalText = #{text};
            AllPageHandles[#{document.handle}].on('dialog', DialogDismissHandler);
          JAVASCRIPT
          block.call
          sleep @reaction_timeout
          @context.eval 'ModalText'
        ensure
          matched = await <<~JAVASCRIPT
            LastResult = ModalTextMatched;
            ModalTextMatched = false;
            ModalText = null;
            AllPageHandles[#{document.handle}].removeListener('dialog', DialogDismissHandler);
          JAVASCRIPT
          raise Isomorfeus::Puppetmaster::ModalNotFound if options.has_key?(:text) && !matched
        end
document_dispatch_event(document, name, event_type = nil, **options) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 258
        def document_dispatch_event(document, name, event_type = nil, **options)
          raise ArgumentError, 'Unknown event' unless EVENTS.key?(name.to_sym) || event_type
          event_type, opts = *EVENTS[name.to_s.downcase.tr('_', '').to_sym] if event_type.nil?
          opts.merge!(options)
          await <<~JAVASCRIPT
            handle = await AllPageHandles[#{document.handle}].evaluate(function(node){
              var event = new #{event_type}('#{name}'#{opts.empty? ? '' : opts});
              document.dispatchEvent(event);
            });
          JAVASCRIPT
        end
document_double_click(document, x: nil, y: nil, modifiers: nil) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 270
        def document_double_click(document, x: nil, y: nil, modifiers: nil)
          # modifier_keys: :alt, :control, :meta, :shift
          modifiers = [modifiers] if modifiers.is_a?(Symbol)
          modifiers = [] unless modifiers
          modifiers = modifiers.map {|key| key.to_s.camelize(:lower) }
          await <<~JAVASCRIPT
            var response_event_occurred = false;
            var response_handler = function(event){ response_event_occurred = true; };
            var response_watcher = new Promise(function(resolve, reject){
              setTimeout(function(){
                if (!response_event_occurred) { resolve(true); } 
                else { setTimeout(function(){ resolve(true); }, #{@puppeteer_timeout}); }
                AllPageHandles[#{document.handle}].removeListener('response', response_handler);
              }, #{@puppeteer_reaction_timeout});
            });
            AllPageHandlers[#{document.handle}].on('response', response_handler);
            var navigation_watcher = AllPageHandles[#{document.handle}].waitForNavigation();
            await AllPageHandles[#{document.handle}].evaluate(function(){
              var options = {button: 0, bubbles: true, cancelable: true};
              var node = window;
              var x = #{x ? x : 'null'};
              var y = #{y ? y : 'null'};
              var modifiers = #{modifiers};
              if (x && y) {
                options['clientX'] = x;
                options['clientY'] = y;
                var n = document.elementFromPoint(x, y);
                if (n) { node = n };
              }
              if (modifiers.includes('meta')) { options['metaKey'] = true; }
              if (modifiers.includes('control')) { options['ctrlKey'] = true; }
              if (modifiers.includes('shift')) { options['shiftKey'] = true; }
              if (modifiers.includes('alt')) { options['altKey'] = true; }
              node.dispatchEvent(new MouseEvent('mousedown', options));
              node.dispatchEvent(new MouseEvent('mouseup', options));
              node.dispatchEvent(new MouseEvent('dblclick', options));
            });
            await Promise.race([response_watcher, navigation_watcher]);
          JAVASCRIPT
        end
document_evaluate_script(document, script, *args) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 311
        def document_evaluate_script(document, script, *args)
          await <<~JAVASCRIPT
            var result = await AllPageHandles[#{document.handle}].evaluate((arguments) => {
              try {
                var res = (function(arguments) {
                  return #{script.strip};
                })(arguments);
                return [res, null];
              } catch (err) {
                return [null, {name: err.name, message: err.message, stack: err.stack}]; 
              }
            }, #{args});
            if (result) {
              LastResult = result[0];
              LastErr = result[1];
            }
          JAVASCRIPT
        end
document_execute_script(document, script, *args) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 330
        def document_execute_script(document, script, *args)
          await <<~JAVASCRIPT
            var result = await AllPageHandles[#{document.handle}].evaluate((arguments) => {
              try {
                var res = (function(arguments) {
                  #{script.strip};
                })(arguments);
                return [res, null];
              } catch (err) {
                return [null, {name: err.name, message: err.message, stack: err.stack}]; 
              } 
            }, #{args});
            if (result) {
              LastResult = result[0];
              LastErr = result[1];
            }
          JAVASCRIPT
        end
document_find(document, selector) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 349
        def document_find(document, selector)
          js_escaped_selector = selector.gsub('\\', '\\\\\\').gsub('"', '\"')
          node_data = await <<~JAVASCRIPT
            var element_handle = await AllPageHandles[#{document.handle}].$("#{js_escaped_selector}");
            if (element_handle) {
              var node_handle = RegisterElementHandle(element_handle);
              var tt = await AllPageHandles[#{document.handle}].evaluate((node) => {
                var tag = node.tagName ? node.tagName.toLowerCase() : '';
                var name = node.nodeName;
                var type = null;
                if (tag === 'input') { type = node.getAttribute('type'); }
                return [name, tag, type, node.isContentEditable];
              }, AllElementHandles[node_handle]);
              LastResult = {handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]};
            }
          JAVASCRIPT
          if node_data
            node_data[:css_selector] = selector
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          else
            raise Isomorfeus::Puppetmaster::ElementNotFound.new(selector)
          end
        end
document_find_all(document, selector) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 373
        def document_find_all(document, selector)
          js_escaped_selector = selector.gsub('\\', '\\\\\\').gsub('"', '\"')
          node_data_array = await <<~JAVASCRIPT
            var node_data_array = [];
            var element_handle_array = await AllPageHandles[#{document.handle}].$$("#{js_escaped_selector}");
            if (element_handle_array) {
              for (var i=0; i<element_handle_array.length; i++) {
                var node_handle = RegisterElementHandle(element_handle_array[i]);
                var tt = await AllPageHandles[#{document.handle}].evaluate((node) => {
                  var tag = node.tagName ? node.tagName.toLowerCase() : '';
                  var name = node.nodeName;
                  var type = null;
                  if (tag === 'input') { type = node.getAttribute('type'); }
                  return [name, tag, type, node.isContentEditable];
                }, AllElementHandles[node_handle]);
                node_data_array.push({handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]});
              }  
            }
            LastResult = node_data_array;
          JAVASCRIPT
          node_data_array.map do |node_data|
            node_data[:css_selector] = selector
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          end
        end
document_find_all_xpath(document, query) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 399
        def document_find_all_xpath(document, query)
          js_escaped_query = query.gsub('\\', '\\\\\\').gsub('"', '\"')
          node_data_array = await <<~JAVASCRIPT
            var node_data_array = [];
            var element_handle_array = await AllPageHandles[#{document.handle}].$x("#{js_escaped_query}");
            if (element_handle_array) {  
              for (var i=0; i<element_handle_array.length; i++) {
                var node_handle = RegisterElementHandle(element_handle_array[i]);
                var tt = await AllPageHandles[#{document.handle}].evaluate((node) => {
                  var tag = node.tagName ? node.tagName.toLowerCase() : '';
                  var name = node.nodeName;
                  var type = null;
                  if (tag === 'input') { type = node.getAttribute('type'); }
                  return [name, tag, type, node.isContentEditable];
                }, AllElementHandles[node_handle]);
                node_data_array.push({handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]});
              }
            }
            LastResult = node_data_array;
          JAVASCRIPT
          node_data_array.map do |node_data|
            node_data[:xpath_query] = query
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          end
        end
document_find_xpath(document, query) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 425
        def document_find_xpath(document, query)
          js_escaped_query = query.gsub('\\', '\\\\\\').gsub('"', '\"')
          node_data = await <<~JAVASCRIPT
            var element_handle_array = await AllPageHandles[#{document.handle}].$x("#{js_escaped_query}");
            var element_handle = (element_handle_array) ? element_handle_array[0] : null;
            if (element_handle) {
              var node_handle = RegisterElementHandle(element_handle);
              var tt = await AllPageHandles[#{document.handle}].evaluate((node) => {
                var tag = node.tagName ? node.tagName.toLowerCase() : '';
                var name = node.nodeName;
                var type = null;
                if (tag === 'input') { type = node.getAttribute('type'); }
                return [name, tag, type, node.isContentEditable];
              }, AllElementHandles[node_handle]);
              LastResult = {handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]};
            }
          JAVASCRIPT
          if node_data
            node_data[:xpath_query] = query
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          else
            raise Isomorfeus::Puppetmaster::ElementNotFound.new(query)
          end
        end
document_go_back(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 450
        def document_go_back(document)
          response_hash, messages = await <<~JAVASCRIPT
            ConsoleMessages[#{document.handle}] = [];
            var response = await AllPageHandles[#{document.handle}].goBack();
            if (response) {
              var request = response.request();
              var formatted_response = {
                headers: response.headers(),
                ok: response.ok(),
                remote_address: response.remoteAddress(),
                request: {
                  failure: request.failure(),
                  headers: request.headers(),
                  method: request.method(),
                  post_data: request.postData(),
                  resource_type: request.resourceType(),
                  url: request.url()
                },
                status: response.status(),
                status_text: response.statusText(),
                text: response.text(),
                url: response.url()
              };
              LastResult = [formatted_response, ConsoleMessages[#{document.handle}]];
            } else {
              LastResult = [null, ConsoleMessages[#{document.handle}]];
            }
          JAVASCRIPT
          con_messages = messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
          con_messages.each { |m| raise determine_error({ 'message' => m.text }) if m.level == 'error' && !m.text.start_with?('Failed to load resource:') }
          if response_hash
            response = Isomorfeus::Puppetmaster::Response.new(response_hash)
            document.instance_variable_set(:@response, response)
          end
          document.response
        end
document_go_forward(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 487
        def document_go_forward(document)
          response_hash, messages = await <<~JAVASCRIPT
            ConsoleMessages[#{document.handle}] = [];
            var response = await AllPageHandles[#{document.handle}].goForward();
            if (response) {
              var request = response.request();
              var formatted_response = {
                headers: response.headers(),
                ok: response.ok(),
                remote_address: response.remoteAddress(),
                request: {
                  failure: request.failure(),
                  headers: request.headers(),
                  method: request.method(),
                  post_data: request.postData(),
                  resource_type: request.resourceType(),
                  url: request.url()
                },
                status: response.status(),
                status_text: response.statusText(),
                text: response.text(),
                url: response.url()
              };
              LastResult = [formatted_response, ConsoleMessages[#{document.handle}]];
            } else {
              LastResult = [null, ConsoleMessages[#{document.handle}]];
            }
          JAVASCRIPT
          con_messages = messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
          con_messages.each { |m| raise determine_error({ 'message' => m.text }) if m.level == 'error' && !m.text.start_with?('Failed to load resource:') }
          if response_hash
            response = Isomorfeus::Puppetmaster::Response.new(response_hash)
            document.instance_variable_set(:@response, response)
          end
          document.response
        end
document_goto(document, uri) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 524
        def document_goto(document, uri)
          parsed_uri = URI.parse(uri)
          parsed_uri.host = @app.host unless parsed_uri.host
          parsed_uri.port = @app.port unless parsed_uri.port
          parsed_uri.scheme = @app.scheme unless parsed_uri.scheme
          response_hash, messages = await <<~JAVASCRIPT
            ConsoleMessages[#{document.handle}] = [];
            var response = await AllPageHandles[#{document.handle}].goto('#{parsed_uri.to_s}');
            if (response) {
              var request = response.request();
              var formatted_response = {
                headers: response.headers(),
                ok: response.ok(),
                remote_address: response.remoteAddress(),
                request: {
                  failure: request.failure(),
                  headers: request.headers(),
                  method: request.method(),
                  post_data: request.postData(),
                  resource_type: request.resourceType(),
                  url: request.url()
                },
                status: response.status(),
                status_text: response.statusText(),
                text: response.text(),
                url: response.url()
              };
              LastResult = [formatted_response, ConsoleMessages[#{document.handle}]];
            } else {
              LastResult = [null, ConsoleMessages[#{document.handle}]];
            }
          JAVASCRIPT
          con_messages = messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
          con_messages.each { |m| raise determine_error({ 'message' => m.text }) if m.level == 'error' && !m.text.start_with?('Failed to load resource:') }
          if response_hash
            response = Isomorfeus::Puppetmaster::Response.new(response_hash)
            document.instance_variable_set(:@response, response)
          end
          document.response
        end
document_head(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 565
        def document_head(document)
          node_data = await <<~JAVASCRIPT
            var element_handle = await AllPageHandles[#{document.handle}].$('head');
            if (element_handle) {
              var node_handle = RegisterElementHandle(element_handle);
              var tt = await AllElementHandles[node_handle].executionContext().evaluate((node) => {
                var name = node.nodeName;
                var tag = node.tagName.toLower();
                return [name, tag, null, node.isContentEditable];
              }, AllElementHandles[node_handle]);
              LastResult = {handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]};
            }
          JAVASCRIPT
          if node_data
            node_data[:css_selector] = selector
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          end
        end
document_html(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 584
def document_html(document)
  await "LastResult = await AllPageHandles[#{document.handle}].content();"
end
document_open_new_document(_document, uri = nil) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 588
        def document_open_new_document(_document, uri = nil)
          if !uri || uri == 'about:blank'
            parsed_uri = 'about:blank'
          else
            parsed_uri = URI.parse(uri)
            parsed_uri.host = @app.host unless parsed_uri.host
            parsed_uri.port = @app.port unless parsed_uri.port
            parsed_uri.scheme = @app.scheme unless parsed_uri.scheme
          end
          handle, response_hash, messages = await <<~JAVASCRIPT
            var new_page = await CurrentBrowser.newPage();
            var url = '#{parsed_uri.to_s}';
            new_page.setDefaultTimeout(#{@puppeteer_timeout});
            await new_page.setViewport({width: #{@width}, height: #{@height}});
            var new_target = new_page.target();
            var cdp_session = await new_target.createCDPSession();
            await cdp_session.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: '#{Isomorfeus::Puppetmaster.download_path}'});
            if (#{@url_blacklist}.length > 0) { await cdp_session.send('Network.setBlockedURLs', {urls: #{@url_blacklist}}); }
            await cdp_session.detach();
            var page_handle = RegisterPage(new_page); 
            var result_response = null;
            if (url && url !== '') { 
              var response = await new_page.goto(url);
              if (response) {
                var request = response.request();
                result_response = {
                  headers: response.headers(),
                  ok: response.ok(),
                  remote_address: response.remoteAddress(),
                  request: {
                    failure: request.failure(),
                    headers: request.headers(),
                    method: request.method(),
                    post_data: request.postData(),
                    resource_type: request.resourceType(),
                    url: request.url()
                  },
                  status: response.status(),
                  status_text: response.statusText(),
                  text: response.text(),
                  url: response.url()
                } 
              }
            };
            LastResult = [page_handle, result_response, ConsoleMessages[page_handle]];
          JAVASCRIPT
          con_messages = messages.map {|m| Isomorfeus::Puppetmaster::ConsoleMessage.new(m)}
          con_messages.each { |m| raise determine_error({ 'message' => m.text }) if m.level == 'error' && !m.text.start_with?('Failed to load resource:') }
          Isomorfeus::Puppetmaster::Document.new(self, handle, Isomorfeus::Puppetmaster::Response.new(response_hash))
        end
document_reload(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 639
def document_reload(document)
  response_hash = await"LastResult = await AllPageHandles[#{document.handle}].reload();"
  Isomorfeus::Puppetmaster::Response.new(response_hash)
end
document_render_base64(document, **options) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 648
def document_render_base64(document, **options)
  # todo
  # https://pptr.dev/#?product=Puppeteer&version=v1.12.2&show=api-pagescreenshotoptions
  final_options = ["encoding: 'base64'"]
  if options.has_key?(:format)
    options[:format] = 'jpeg' if options[:format].to_s.downcase == 'jpg'
    final_options << "type: '#{options.delete(:format).to_s.downcase}'"
  end
  final_options << "quality: #{options.delete(:quality)}" if options.has_key?(:quality)
  final_options << "fullPage: #{options.delete(:full)}" if options.has_key?(:full)
  options.each do |k,v|
    final_options << "#{k.to_s.camelize(:lower)}: #{v}"
  end
  await "LastResult = await AllPageHandles[#{document.handle}].screenshot({#{final_options.join(', ')}});"
end
document_reset_user_agent(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 664
        def document_reset_user_agent(document)
          await <<~JAVASCRIPT
            var original_user_agent = await CurrentBrowser.userAgent();
            await AllPageHandles[#{document.handle}].setUserAgent(original_user_agent);
          JAVASCRIPT
        end
document_right_click(document, x: nil, y: nil, modifiers: nil) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 671
        def document_right_click(document, x: nil, y: nil, modifiers: nil)
          # modifier_keys: :alt, :control, :meta, :shift
          # offset: { x: int, y: int }
          modifiers = [modifiers] if modifiers.is_a?(Symbol)
          modifiers = [] unless modifiers
          modifiers = modifiers.map {|key| key.to_s.camelize(:lower) }
          await <<~JAVASCRIPT
            var response_event_occurred = false;
            var response_handler = function(event){ response_event_occurred = true; };
            var response_watcher = new Promise(function(resolve, reject){
              setTimeout(function(){
                if (!response_event_occurred) { resolve(true); } 
                else { setTimeout(function(){ resolve(true); }, #{@puppeteer_timeout}); }
                AllPageHandles[#{document.handle}].removeListener('response', response_handler);
              }, #{@puppeteer_reaction_timeout});
            });
            AllPageHandles[#{document.handle}].on('response', response_handler);
            var navigation_watcher = AllPageHandles[#{document.handle}].waitForNavigation();
            await AllPageHandles[#{document.handle}].evaluate(function(){
              var options = {button: 2, bubbles: true, cancelable: true};
              var node = window;
              var x = #{x ? x : 'null'};
              var y = #{y ? y : 'null'};
              var modifiers = #{modifiers};
              if (x && y) {
                options['clientX'] = x;
                options['clientY'] = y;
                var n = document.elementFromPoint(x, y);
                if (n) { node = n };
              }
              if (modifiers.includes('meta')) { options['metaKey'] = true; }
              if (modifiers.includes('control')) { options['ctrlKey'] = true; }
              if (modifiers.includes('shift')) { options['shiftKey'] = true; }
              if (modifiers.includes('alt')) { options['altKey'] = true; }
              node.dispatchEvent(new MouseEvent('mousedown', options));
              node.dispatchEvent(new MouseEvent('mouseup', options));
              node.dispatchEvent(new MouseEvent('contextmenu', options));
            });
            await Promise.race([response_watcher, navigation_watcher]);
          JAVASCRIPT
        end
document_save_pdf(document, path, **options) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 713
def document_save_pdf(document, path, **options)
  # todo
  # https://pptr.dev/#?product=Puppeteer&version=v1.12.2&show=api-pagepdfoptions
  absolute_path = File.absolute_path(path)
  final_options = ["path: '#{absolute_path}'"]
  final_options << "format: '#{options.delete(:format)}'" if options.has_key?(:format)
  final_options << "headerTemplate: `#{options.delete(:header_template)}`" if options.has_key?(:header_template)
  final_options << "footerTemplate: `#{options.delete(:footer_template)}`" if options.has_key?(:footer_template)
  final_options << "pageRanges: '#{options.delete(:page_ranges)}'" if options.has_key?(:page_ranges)
  final_options << "width: '#{options.delete(:width)}'" if options.has_key?(:width)
  final_options << "height: '#{options.delete(:height)}'" if options.has_key?(:height)
  options.each do |k,v|
    final_options << "#{k.to_s.camelize(:lower)}: #{v}"
  end
  await "await AllPageHandles[#{document.handle}].pdf({#{final_options.join(', ')}});"
end
document_save_screenshot(document, path, **options) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 730
def document_save_screenshot(document, path, **options)
  # todo
  # https://pptr.dev/#?product=Puppeteer&version=v1.12.2&show=api-pagescreenshotoptions
  absolute_path = File.absolute_path(path)
  final_options = ["path: '#{absolute_path}'"]
  if options.has_key?(:format)
    options[:format] = 'jpeg' if options[:format].to_s.downcase == 'jpg'
    final_options << "type: '#{options.delete(:format).to_s.downcase}'"
  end
  final_options << "quality: #{options.delete(:quality)}" if options.has_key?(:quality)
  final_options << "fullPage: #{options.delete(:full)}" if options.has_key?(:full)
  options.each do |k,v|
    final_options << "#{k.to_s.camelize(:lower)}: #{v}"
  end
  await "await AllPageHandles[#{document.handle}].screenshot({#{final_options.join(', ')}});"
end
document_scroll_by(document, x, y) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 747
def document_scroll_by(document, x, y)
  await "await AllPageHandles[#{document.handle}].evaluate('window.scrollBy(#{x}, #{y})');"
end
document_scroll_to(document, x, y) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 751
def document_scroll_to(document, x, y)
  await "await AllPageHandles[#{document.handle}].evaluate('window.scrollTo(#{x}, #{y})');"
end
document_set_authentication_credentials(document, username, password) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 755
def document_set_authentication_credentials(document, username, password)
  await "await AllPageHandles[#{document.handle}].authenticate({username: '#{username}', password: '#{password}'});"
end
document_set_extra_headers(document, headers_hash) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 785
def document_set_extra_headers(document, headers_hash)
  await "await AllPageHandles[#{document.handle}].setExtraHTTPHeaders(#{Oj.dump(headers_hash, mode: :strict)});"
end
document_set_url_blacklist(document, url_array) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 789
        def document_set_url_blacklist(document, url_array)
          # https://www.chromium.org/administrators/url-blacklist-filter-format
          @url_blacklist = url_array
          await <<~JAVASCRIPT
            var cdp_session = await AllPageHandles[#{document.handle}].target().createCDPSession();
            await cdp_session.send('Network.setBlockedURLs', {urls: #{url_array}});
            await cdp_session.detach();
          JAVASCRIPT
        end
document_set_user_agent(document, agent_string) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 799
def document_set_user_agent(document, agent_string)
  await "await AllPageHandles[#{document.handle}].setUserAgent('#{agent_string}');"
end
document_title(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 803
def document_title(document)
  await "LastResult = await AllPageHandles[#{document.handle}].title();"
end
document_type_keys(document, *keys) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 807
def document_type_keys(document, *keys)
  cjs = "await AllPageHandles[#{document.handle}].bringToFront();"
  top_modifiers = []
  keys.each do |key|
    if key.is_a?(String)
      key.each_char do |c|
        need_shift = /[[:upper:]]/.match(c)
        cjs << "await AllPageHandles[#{document.handle}].keyboard.down('Shift');\n" if need_shift
        c = "Key#{c.upcase}" if /[[:alpha:]]/.match(c)
        cjs << "await AllPageHandles[#{document.handle}].keyboard.down('#{c}');\n"
        cjs << "await AllPageHandles[#{document.handle}].keyboard.up('#{c}');\n"
        cjs << "await AllPageHandles[#{document.handle}].keyboard.up('Shift');\n" if need_shift
      end
    elsif key.is_a?(Symbol)
      if %i[ctrl Ctrl].include?(key)
        key = :control
      elsif  %i[command Command Meta].include?(key)
        key = :meta
      elsif  %i[divide Divide].include?(key)
        key = :numpad_divide
      elsif  %i[decimal Decimal].include?(key)
        key = :numpad_decimal
      elsif %i[left right up down].include?(key)
        key = "arrow_#{key}".to_sym
      end
      if %i[alt alt_left alt_right control control_left control_rigth meta meta_left meta_right shift shift_left shift_right].include?(key)
        top_modifiers << key
        cjs << "await AllPageHandles[#{document.handle}].keyboard.down('#{key.to_s.camelize}');\n"
      else
        cjs << "await AllPageHandles[#{document.handle}].keyboard.press('#{key.to_s.camelize}');\n"
      end
    elsif key.is_a?(Array)
      modifiers = []
      key.each do |k|
        if k.is_a?(Symbol)
          if %i[ctrl Ctrl].include?(k)
            k = :control
          elsif  %i[command Command Meta].include?(k)
            k = :meta
          elsif  %i[divide Divide].include?(k)
            k = :numpad_divide
          elsif  %i[decimal Decimal].include?(k)
            k = :numpad_decimal
          elsif %i[left right up down].include?(key)
            k = "arrow_#{key}".to_sym
          end
          if %i[alt alt_left alt_right control control_left control_rigth meta meta_left meta_right shift shift_left shift_right].include?(k)
            modifiers << k
            cjs << "await AllPageHandles[#{document.handle}].keyboard.down('#{k.to_s.camelize}');\n"
          else
            cjs << "await AllPageHandles[#{document.handle}].keyboard.press('#{k.to_s.camelize}');\n"
          end
        elsif k.is_a?(String)
          k.each_char do |c|
            need_shift = /[[:upper:]]/.match(c)
            cjs << "await AllPageHandles[#{document.handle}].keyboard.down('Shift');\n" if need_shift
            c = "Key#{c.upcase}" if /[[:alpha:]]/.match(c)
            cjs << "await AllPageHandles[#{document.handle}].keyboard.press('#{c}');\n"
            cjs << "await AllPageHandles[#{document.handle}].keyboard.up('Shift');\n" if need_shift
          end
        end
      end
      modifiers.reverse.each do |k|
        cjs << "await AllPageHandles[#{document.handle}].keyboard.up('#{k.to_s.camelize}');\n"
      end
    end
  end
  top_modifiers.reverse.each do |key|
    cjs << "await AllPageHandles[#{document.handle}].keyboard.up('#{key.to_s.camelize}');\n"
  end
  await(cjs)
end
document_url(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 880
def document_url(document)
  await "LastResult = await AllPageHandles[#{document.handle}].evaluate('window.location.href');"
end
document_user_agent(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 884
def document_user_agent(document)
  await "LastResult = await AllPageHandles[#{document.handle}].evaluate('window.navigator.userAgent');"
end
document_viewport_maximize(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 888
def document_viewport_maximize(document)
  document_viewport_resize(document, @max_width, @max_height)
end
document_viewport_resize(document, width, height) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 892
def document_viewport_resize(document, width, height)
  width = @max_width if width > @max_width
  height = @max_height if width > @max_height
  await "await AllPageHandles[#{document.handle}].setViewport({width: #{width}, height: #{height}});"
end
document_viewport_size(document) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 898
def document_viewport_size(document)
  viewport = @context.eval "AllPageHandles[#{document.handle}].viewport()"
  [viewport['width'], viewport['height']]
end
document_wait_for(document, selector) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 903
        def document_wait_for(document, selector)
          js_escaped_selector = selector.gsub('\\', '\\\\\\').gsub('"', '\"')
          node_data = await <<~JAVASCRIPT
            var element_handle = await AllPageHandles[#{document.handle}].waitForSelector("#{js_escaped_selector}");
            if (element_handle) {
              var node_handle = RegisterElementHandle(element_handle);
              var tt = await AllElementHandles[node_handle].executionContext().evaluate((node) => {
                var name = node.nodeName;
                var tag = node.tagName.toLowerCase();
                var type = null;
                if (tag === 'input') { type = node.getAttribute('type'); }
                return [name, tag, type, node.isContentEditable];
              }, AllElementHandles[node_handle]);
              LastResult = {handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]};
            }
          JAVASCRIPT
          if node_data
            node_data[:css_selector] = selector
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          else
            raise Isomorfeus::Puppetmaster::ElementNotFound.new(selector)
          end
        end
document_wait_for_xpath(document, query) click to toggle source
# File lib/isomorfeus/puppetmaster/driver/puppeteer_document.rb, line 927
        def document_wait_for_xpath(document, query)
          js_escaped_query = query.gsub('\\', '\\\\\\').gsub('"', '\"')
          node_data = await <<~JAVASCRIPT
            var element_handle = await AllPageHandles[#{document.handle}].waitForXPath("#{js_escaped_query}");
            if (element_handle) {
              var node_handle = RegisterElementHandle(element_handle);
              var tt = await AllElementHandles[node_handle].executionContext().evaluate((node) => {
                var name = node.nodeName;
                var tag = node.tagName.toLowerCase();
                var type = null;
                if (tag === 'input') { type = node.getAttribute('type'); }
                return [name, tag, type, node.isContentEditable];
              }, AllElementHandles[node_handle]);
              LastResult = {handle: node_handle, name: tt[0], tag: tt[1], type: tt[2], content_editable: tt[3]};
            }
          JAVASCRIPT
          if node_data
            node_data[:xpath_query] = query
            Isomorfeus::Puppetmaster::Node.new_by_tag(self, document, node_data)
          else
            raise Isomorfeus::Puppetmaster::ElementNotFound.new(selector)
          end
        end