Royce  Reinger

Royce Reinger

1658095740

Poltergeist: A PhantomJS Driver for Capybara

Poltergeist - A PhantomJS driver for Capybara

Poltergeist is a driver for Capybara. It allows you to run your Capybara tests on a headless PhantomJS browser. If you would like to run your tests on headless Chrome there's another project Cuprite claims to be compatible with Poltergeist.

Installation

Add this line to your Gemfile and run bundle install:

gem 'poltergeist'

In your test setup add:

require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist

If you were previously using the :rack_test driver, be aware that your app will now run in a separate thread and this can have consequences for transactional tests. See the Capybara README for more detail.

Installing PhantomJS

You need at least PhantomJS 1.8.1. There are no other external dependencies (you don't need Qt, or a running X server, etc.)

Mac

  • Homebrew: brew tap homebrew/cask && brew cask install phantomjs
  • MacPorts: sudo port install phantomjs
  • Manual install: Download this

Linux

  • Download the 32 bit or 64 bit binary.
  • Extract the tarball and copy bin/phantomjs into your PATH

DO NOT use phantomjs from the official Ubuntu repositories, since it doesn't work well with poltergeist. More information here.

Windows

Manual compilation

Do this as a last resort if the binaries don't work for you. It will take quite a long time as it has to build WebKit.

(See also the PhantomJS building guide.)

Compatibility

Poltergeist runs on MRI 1.9+, JRuby 1.9+ and Rubinius 1.9+. Poltergeist and PhantomJS are currently supported on Mac OS X, Linux, and Windows platforms.

Ruby 1.8 is no longer supported. The last release to support Ruby 1.8 was 1.0.2, so you should use that if you still need Ruby 1.8 support.

PhantomJS does not support ES6 features at the time of writing this document. Setting js_errors to true can help determine if failing tests require Polyfills, although a bug in PhantomJS can cause silent failures if using ES6 features like let, const, etc.

Running on a CI

There are no special steps to take. You don't need Xvfb or any running X server at all.

Travis CI, CircleCI, Codeship and Semaphore have PhantomJS pre-installed.

Depending on your tests, one thing that you may need is some fonts. If you're getting errors on a CI that don't occur during development then try taking some screenshots - it may well be missing fonts throwing things off kilter. Your distro will have various font packages available to install.

What's supported?

Poltergeist supports all the mandatory features for a Capybara driver, and the following optional features:

  • page.evaluate_script and page.execute_script
  • page.within_frame
  • page.status_code
  • page.response_headers
  • page.save_screenshot
  • page.driver.render_base64(format, options)
  • page.driver.scroll_to(left, top)
  • page.driver.basic_authorize(user, password)
  • element.send_keys(*keys)
  • page.driver.set_proxy(ip, port, type, user, password)
  • window API
  • cookie handling
  • drag-and-drop

There are some additional features:

Taking screenshots with some extensions

You can grab screenshots of the page at any point by calling save_screenshot('/path/to/file.png') (this works the same way as the PhantomJS render feature, so you can specify other extensions like .pdf, .gif, etc.) Just in case you render pdf it's might be worth to set driver.paper_size= with settings provided by PhantomJS in here

By default, only the viewport will be rendered (the part of the page that is in view). To render the entire page, use save_screenshot('/path/to/file.png', :full => true).

You also have an ability to render selected element. Pass option selector with any valid CSS element selector to make a screenshot bounded by that element save_screenshot('/path/to/file.png', :selector => '#id').

If you need for some reasons base64 encoded screenshot you can simply call render_base64 that will return you encoded image. Additional options are the same as for save_screenshot except the first argument which is format (:png by default, acceptable :png, :gif, :jpeg).

Clicking precise coordinates

Sometimes its desirable to click a very specific area of the screen. You can accomplish this with page.driver.click(x, y), where x and y are the screen coordinates.

Remote debugging (experimental)

If you use the :inspector => true option (see below), remote debugging will be enabled.

When this option is enabled, you can insert page.driver.debug into your tests to pause the test and launch a browser which gives you the WebKit inspector to view your test run with.

You can register this debugger driver with a different name and set it as the current javascript driver. By example, in your helper file:

Capybara.register_driver :poltergeist_debug do |app|
  Capybara::Poltergeist::Driver.new(app, :inspector => true)
end

# Capybara.javascript_driver = :poltergeist
Capybara.javascript_driver = :poltergeist_debug

Read more here

Manipulating request headers

You can manipulate HTTP request headers with these methods:

page.driver.headers # => {}
page.driver.headers = { "User-Agent" => "Poltergeist" }
page.driver.add_headers("Referer" => "https://example.com")
page.driver.headers # => { "User-Agent" => "Poltergeist", "Referer" => "https://example.com" }

Notice that headers= will overwrite already set headers. You should use add_headers if you want to add a few more. These headers will apply to all subsequent HTTP requests (including requests for assets, AJAX, etc). They will be automatically cleared at the end of the test. You have ability to set headers only for the initial request:

page.driver.headers = { "User-Agent" => "Poltergeist" }
page.driver.add_header("Referer", "http://example.com", permanent: false)
page.driver.headers # => { "User-Agent" => "Poltergeist", "Referer" => "http://example.com" }
visit(login_path)
page.driver.headers # => { "User-Agent" => "Poltergeist" }

This way your temporary headers will be sent only for the initial request, and related 30x redirects. All subsequent request will only contain your permanent headers. If the temporary headers should not be sent on related 30x redirects, specify permanent: :no_redirect.

Headers set with any of these methods will be set within all windows in the session, with the exception of temporary headers, which are only set within the current window.

Inspecting network traffic

You can inspect the network traffic (i.e. what resources have been loaded) on the current page by calling page.driver.network_traffic. This returns an array of request objects. A request object has a response_parts method containing data about the response chunks.

You can inspect requests that were blocked by a whitelist or blacklist by calling page.driver.network_traffic(:blocked). This returns an array of request objects. The response_parts portion of these requests will always be empty.

Please note that network traffic is not cleared when you visit new page. You can manually clear the network traffic by calling page.driver.clear_network_traffic or page.driver.reset

Manipulating cookies

The following methods are used to inspect and manipulate cookies:

  • page.driver.cookies - a hash of cookies accessible to the current page. The keys are cookie names. The values are Cookie objects, with the following methods: name, value, domain, path, secure?, httponly?, samesite, expires.
  • page.driver.set_cookie(name, value, options = {}) - set a cookie. The options hash can take the following keys: :domain, :path, :secure, :httponly, :samesite, :expires. :expires should be a Time object.
  • page.driver.remove_cookie(name) - remove a cookie
  • page.driver.clear_cookies - clear all cookies

Sending keys

There's an ability to send arbitrary keys to the element:

element = find('input#id')
element.send_keys('String')

or even more complicated:

element.send_keys('H', 'elo', :left, 'l') # => 'Hello'
element.send_keys(:enter) # triggers Enter key

Since it's implemented natively in PhantomJS this will exactly imitate user behavior. See more about sendEvent and PhantomJS keys

Customization

You can customize the way that Capybara sets up Poltergeist via the following code in your test setup:

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, options)
end

options is a hash of options. The following options are supported:

  • :phantomjs (String) - A custom path to the phantomjs executable
  • :debug (Boolean) - When true, debug output is logged to STDERR. Some debug info from the PhantomJS portion of Poltergeist is also output, but this goes to STDOUT due to technical limitations.
  • :logger (Object responding to puts) - When present, debug output is written to this object
  • :phantomjs_logger (IO object) - Where the STDOUT from PhantomJS is written to. This is where your console.log statements will show up. Default: STDOUT
  • :timeout (Numeric) - The number of seconds we'll wait for a response when communicating with PhantomJS. Default is 30.
  • :inspector (Boolean, String) - See 'Remote Debugging', above.
  • :js_errors (Boolean) - When false, JavaScript errors do not get re-raised in Ruby.
  • :window_size (Array) - The dimensions of the browser window in which to test, expressed as a 2-element array, e.g. [1024, 768]. Default: [1024, 768]
  • :screen_size (Array) - The dimensions the window size will be set to when Window#maximize is called. Expressed as a 2-element array, e.g. [1600, 1200]. Default: [1366, 768]
  • :phantomjs_options (Array) - Additional command line options to be passed to PhantomJS, e.g. ['--load-images=no', '--ignore-ssl-errors=yes']
  • :extensions (Array) - An array of JS files to be preloaded into the phantomjs browser. Useful for faking unsupported APIs.
  • :port (Fixnum) - The port which should be used to communicate with the PhantomJS process. Defaults to a random open port.
  • :host (String) - The name or IP of the PhantomJS host. Default is '127.0.0.1'.
  • :url_blacklist (Array) - Default session url blacklist - expressed as an array of strings to match against requested URLs.
  • :url_whitelist (Array) - Default session url whitelist - expressed as an array of strings to match against requested URLs.
  • :page_settings (Hash) - PhantomJS web page settings (http://phantomjs.org/api/webpage/property/settings.html).

URL Blacklisting & Whitelisting

Poltergeist supports URL blacklisting, which allows you to prevent scripts from running on designated domains:

page.driver.browser.url_blacklist = ['http://www.example.com']

and also URL whitelisting, which allows scripts to only run on designated domains:

page.driver.browser.url_whitelist = ['http://www.example.com']

If you are experiencing slower run times, consider creating a URL whitelist of domains that are essential or a blacklist of domains that are not essential, such as ad networks or analytics, to your testing environment.

Troubleshooting

Unfortunately, the nature of full-stack testing is that things can and do go wrong from time to time. This section aims to highlight a number of common problems and provide ideas about how you can work around them.

DeadClient errors

Sometimes PhantomJS crashes during a test. There are basically two kinds of crashes: those that can be reproduced every time, and those that occur sporadically and are not easily reproduced.

If your crash happens every time, you should read the PhantomJS crash reporting guide and file a bug against PhantomJS. Feel free to also file a bug against Poltergeist in case there are workarounds that can be implemented within Poltergeist. Also, if lots of Poltergeist users are experiencing the same crash then fixing it will move up the priority list.

If your crash is sporadic, there is less that can be done. Often these issues are very complicated and difficult to track down. It may be that the crash has already been fixed in a newer version of WebKit that will eventually find its way into PhantomJS. It's still worth reporting your bug against PhantomJS, but it's probably not worth filing a bug against Poltergeist as there's not much we can do.

If you experience sporadic crashes a lot, it may be worth configuring your CI to automatically re-run failing tests before reporting a failed build.

MouseEventFailed errors

When Poltergeist clicks on an element, rather than generating a DOM click event, it actually generates a "proper" click. This is much closer to what happens when a real user clicks on the page - but it means that Poltergeist must scroll the page to where the element is, and work out the correct co-ordinates to click. If the element is covered up by another element, the click will fail (this is a good thing - because your user won't be able to click a covered up element either).

Sometimes there can be issues with this behavior. If you have problems, it's worth taking screenshots of the page and trying to work out what's going on. If your click is failing, but you're not getting a MouseEventFailed error, then you can turn on the :debug option and look in the output to see what co-ordinates Poltergeist is using for the click. You can then cross-reference this with a screenshot to see if something is obviously wrong.

If you can't figure out what's going on and just want to work around the problem so you can get on with life, consider using a DOM click event. For example, if this code is failing:

click_button "Save"

Then try:

find_button("Save").trigger('click')

Timing problems

Sometimes tests pass and fail sporadically. This is often because there is some problem synchronising events properly. It's often straightforward to verify this by adding sleep statements into your test to allow sufficient time for the page to settle.

If you have these types of problems, read through the Capybara documentation on asynchronous JavaScript which explains the tools that Capybara provides for dealing with this.

Memory leak

If you run a few capybara sessions manually please make sure you've called session.driver.quit when you don't need session anymore. Forgetting about this causes memory leakage and your system's resources can be exhausted earlier than you may expect.

General troubleshooting hints

  • Configure Poltergeist with :debug turned on so you can see its communication with PhantomJS.
  • Take screenshots to figure out what the state of your page is when the problem occurs.
  • Use the remote web inspector in case it provides any useful insight
  • Consider downloading the Poltergeist source and using console.log debugging to figure out what's going on inside PhantomJS. (This will require an understanding of the Poltergeist source code and PhantomJS, so it's only for the committed!)

Filing a bug

If you can provide specific steps to reproduce your problem, or have specific information that might help other help you track down the problem, then please file a bug on Github.

Include as much information as possible. For example:

  • Specific steps to reproduce where possible (failing tests are even better)
  • The output obtained from running Poltergeist with :debug turned on
  • Screenshots
  • Stack traces if there are any Ruby on JavaScript exceptions generated
  • The Poltergeist and PhantomJS version numbers used
  • The operating system name and version used

Changes

Version history and a list of next-release features and fixes can be found in the changelog.

If you're viewing this at https://github.com/teampoltergeist/poltergeist, you're reading the documentation for the master branch. View documentation for the latest release (1.18.1).

Getting help

Questions should be posted on Stack Overflow, using the 'poltergeist' tag.

Bug reports should be posted on GitHub (and be sure to read the bug reporting guidance below).

Author: Teampoltergeist
Source Code: https://github.com/teampoltergeist/poltergeist 
License: MIT license

#ruby #driver 

What is GEEK

Buddha Community

Poltergeist: A PhantomJS Driver for Capybara

Introduction to Browser Drivers in Selenium

Drivers in Selenium are a vital rather a must for Browser automation. Selenium library in Python or in any other programming language uses the particular Browser’s driver to control browsers with their actions, add functionality to it, and in all manipulate data (webpage) in it.

Contrary to the most common way of declaring a Browser’s Driver which is most common, but often may result in incompatibility issues. There are multiple ways (not so common) to install, initialize web drivers in your Python code.

Downloading the Drivers

The foremost point of error in Selenium occurs when the browser’s driver’s version doesn’t match with the browser’s version, for which compatibility issue arises. So, to start with, you must always use the driver with the same version as that of the Web Browser(Google Chrome, Mozilla Firefox, Apple Safari, or any other) which you intend to use for automation.

Downloading and installing Web Drivers is completely safe because these drivers are maintained by the Official Browser Companies and updated accordingly, for testing and automation purposes of their browser and webpages.

Check with your browser which you intend to automate for its version and download the driver from the below references accordingly:

Web BrowserDriver Download Reference
Google Chrome/ChromiumDownload
Mozilla FirefoxDownload
Microsoft EdgeDownload
Apple SafariAlready built-in

Ways to use Drivers

Let’s now look at how we can use the selenium web drivers.

1. Entering the Direct Location

  • The most popular method to use a web driver in Python Selenium code for browser automation. The reason for its popularity is the direct approach it uses, to define a driver in a script.
  • This method requires manual downloading of the web driver.

Advantage: No need to care about lengthy setup or figuring out of Environment variable
Disadvantage: Makes the code less flexible and subject to manual changes for every update

driver = webdriver.Chrome('path/to/chromedriver") 
driver = webdriver.Chrome('C://software/chromedriver.exe') #driver located at the specified location
driver = webdriver.Chrome('chromedriver.exe')  #driver located in the same directory as of the python script file
 
#other way
 
service = Service(executable_path="/path/to/chromedriver")
driver = webdriver.Chrome(service=service)

2. Environment Variable

  • If you have tried the above-mentioned method, then you may have noticed how tiring it is to note/remember the location of your installed web driver in some directory of your computer.
  • To tackle for this problem, we define the location or path of our driver in Environment Variable, once and for all. After successful definition, we do not require specifying the path location in our code, and we can code effortlessly.
  • This method also requires manual installation of the driver, as you might have known this method is used for the issue of path variable.

Advantage: No hassle of specifying the path to the driver
Disadvantage: No update functionality

To set the Environment Path Variable, go to your command prompt and type in the following command:In place of “C:\WebDriver\bin” in the below command, use the path (install location) of the driver.

setx PATH "%PATH%;C:\WebDriver\bin"

If you find this way difficult, then you may search for Environment Variable in your Windows Start Menu and click open -“Edit the system environment variables“. After that, from the pop-up window select “Environment Variables” to open another pop-up window.

From the System Variables option, select open Path and now click on New to introduce a new path variable. Paste the location of your web driver in it, then OK, OK, and finally again OK, in all windows.

Environment VariableEnvironment Variable

3. Driver Manager

The last and probably the most useful method to use is the Web Driver in your Python code. On selecting, automatic updating in Web Browser, the device only updates the browser and not the installed driver, in this case upon execution of python script the code gives error for not equal versions of the browser and driver.

Advantage: No version compatibility issues and help easily switch between multiple browsers
Disadvantage: Maybe a bit difficult to set up for beginners

Install the driver manager

pip install webdriver-manager

Import the manager

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager            # --> for Chrome
 
#from webdriver_manager.firefox import GeckoDriverManager               # --> for Firefox

Now as we have installed and imported the manager, we use it in our code like –

Use the install() method to get the location used by the manager and pass it into a loc_service class. This method informs about the location of the installed web driver by itself.

driver = webdriver.Chrome(ChromeDriverManager().install())   # --> for Chrome
 
#driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())     #--> for Firefox

For any other browser, you may check the official GitHub repository of the driver manager software.

Conclusion

That’s it for the tutorial. Contrary to the popular methods of using the web drivers in Selenium, in this tutorial you learned about the other and maybe advantageous methods to perform the same.  

Link: https://www.askpython.com/python-modules/introduction-browser-drivers-selenium

#python #selenium

Royce  Reinger

Royce Reinger

1658095740

Poltergeist: A PhantomJS Driver for Capybara

Poltergeist - A PhantomJS driver for Capybara

Poltergeist is a driver for Capybara. It allows you to run your Capybara tests on a headless PhantomJS browser. If you would like to run your tests on headless Chrome there's another project Cuprite claims to be compatible with Poltergeist.

Installation

Add this line to your Gemfile and run bundle install:

gem 'poltergeist'

In your test setup add:

require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist

If you were previously using the :rack_test driver, be aware that your app will now run in a separate thread and this can have consequences for transactional tests. See the Capybara README for more detail.

Installing PhantomJS

You need at least PhantomJS 1.8.1. There are no other external dependencies (you don't need Qt, or a running X server, etc.)

Mac

  • Homebrew: brew tap homebrew/cask && brew cask install phantomjs
  • MacPorts: sudo port install phantomjs
  • Manual install: Download this

Linux

  • Download the 32 bit or 64 bit binary.
  • Extract the tarball and copy bin/phantomjs into your PATH

DO NOT use phantomjs from the official Ubuntu repositories, since it doesn't work well with poltergeist. More information here.

Windows

Manual compilation

Do this as a last resort if the binaries don't work for you. It will take quite a long time as it has to build WebKit.

(See also the PhantomJS building guide.)

Compatibility

Poltergeist runs on MRI 1.9+, JRuby 1.9+ and Rubinius 1.9+. Poltergeist and PhantomJS are currently supported on Mac OS X, Linux, and Windows platforms.

Ruby 1.8 is no longer supported. The last release to support Ruby 1.8 was 1.0.2, so you should use that if you still need Ruby 1.8 support.

PhantomJS does not support ES6 features at the time of writing this document. Setting js_errors to true can help determine if failing tests require Polyfills, although a bug in PhantomJS can cause silent failures if using ES6 features like let, const, etc.

Running on a CI

There are no special steps to take. You don't need Xvfb or any running X server at all.

Travis CI, CircleCI, Codeship and Semaphore have PhantomJS pre-installed.

Depending on your tests, one thing that you may need is some fonts. If you're getting errors on a CI that don't occur during development then try taking some screenshots - it may well be missing fonts throwing things off kilter. Your distro will have various font packages available to install.

What's supported?

Poltergeist supports all the mandatory features for a Capybara driver, and the following optional features:

  • page.evaluate_script and page.execute_script
  • page.within_frame
  • page.status_code
  • page.response_headers
  • page.save_screenshot
  • page.driver.render_base64(format, options)
  • page.driver.scroll_to(left, top)
  • page.driver.basic_authorize(user, password)
  • element.send_keys(*keys)
  • page.driver.set_proxy(ip, port, type, user, password)
  • window API
  • cookie handling
  • drag-and-drop

There are some additional features:

Taking screenshots with some extensions

You can grab screenshots of the page at any point by calling save_screenshot('/path/to/file.png') (this works the same way as the PhantomJS render feature, so you can specify other extensions like .pdf, .gif, etc.) Just in case you render pdf it's might be worth to set driver.paper_size= with settings provided by PhantomJS in here

By default, only the viewport will be rendered (the part of the page that is in view). To render the entire page, use save_screenshot('/path/to/file.png', :full => true).

You also have an ability to render selected element. Pass option selector with any valid CSS element selector to make a screenshot bounded by that element save_screenshot('/path/to/file.png', :selector => '#id').

If you need for some reasons base64 encoded screenshot you can simply call render_base64 that will return you encoded image. Additional options are the same as for save_screenshot except the first argument which is format (:png by default, acceptable :png, :gif, :jpeg).

Clicking precise coordinates

Sometimes its desirable to click a very specific area of the screen. You can accomplish this with page.driver.click(x, y), where x and y are the screen coordinates.

Remote debugging (experimental)

If you use the :inspector => true option (see below), remote debugging will be enabled.

When this option is enabled, you can insert page.driver.debug into your tests to pause the test and launch a browser which gives you the WebKit inspector to view your test run with.

You can register this debugger driver with a different name and set it as the current javascript driver. By example, in your helper file:

Capybara.register_driver :poltergeist_debug do |app|
  Capybara::Poltergeist::Driver.new(app, :inspector => true)
end

# Capybara.javascript_driver = :poltergeist
Capybara.javascript_driver = :poltergeist_debug

Read more here

Manipulating request headers

You can manipulate HTTP request headers with these methods:

page.driver.headers # => {}
page.driver.headers = { "User-Agent" => "Poltergeist" }
page.driver.add_headers("Referer" => "https://example.com")
page.driver.headers # => { "User-Agent" => "Poltergeist", "Referer" => "https://example.com" }

Notice that headers= will overwrite already set headers. You should use add_headers if you want to add a few more. These headers will apply to all subsequent HTTP requests (including requests for assets, AJAX, etc). They will be automatically cleared at the end of the test. You have ability to set headers only for the initial request:

page.driver.headers = { "User-Agent" => "Poltergeist" }
page.driver.add_header("Referer", "http://example.com", permanent: false)
page.driver.headers # => { "User-Agent" => "Poltergeist", "Referer" => "http://example.com" }
visit(login_path)
page.driver.headers # => { "User-Agent" => "Poltergeist" }

This way your temporary headers will be sent only for the initial request, and related 30x redirects. All subsequent request will only contain your permanent headers. If the temporary headers should not be sent on related 30x redirects, specify permanent: :no_redirect.

Headers set with any of these methods will be set within all windows in the session, with the exception of temporary headers, which are only set within the current window.

Inspecting network traffic

You can inspect the network traffic (i.e. what resources have been loaded) on the current page by calling page.driver.network_traffic. This returns an array of request objects. A request object has a response_parts method containing data about the response chunks.

You can inspect requests that were blocked by a whitelist or blacklist by calling page.driver.network_traffic(:blocked). This returns an array of request objects. The response_parts portion of these requests will always be empty.

Please note that network traffic is not cleared when you visit new page. You can manually clear the network traffic by calling page.driver.clear_network_traffic or page.driver.reset

Manipulating cookies

The following methods are used to inspect and manipulate cookies:

  • page.driver.cookies - a hash of cookies accessible to the current page. The keys are cookie names. The values are Cookie objects, with the following methods: name, value, domain, path, secure?, httponly?, samesite, expires.
  • page.driver.set_cookie(name, value, options = {}) - set a cookie. The options hash can take the following keys: :domain, :path, :secure, :httponly, :samesite, :expires. :expires should be a Time object.
  • page.driver.remove_cookie(name) - remove a cookie
  • page.driver.clear_cookies - clear all cookies

Sending keys

There's an ability to send arbitrary keys to the element:

element = find('input#id')
element.send_keys('String')

or even more complicated:

element.send_keys('H', 'elo', :left, 'l') # => 'Hello'
element.send_keys(:enter) # triggers Enter key

Since it's implemented natively in PhantomJS this will exactly imitate user behavior. See more about sendEvent and PhantomJS keys

Customization

You can customize the way that Capybara sets up Poltergeist via the following code in your test setup:

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, options)
end

options is a hash of options. The following options are supported:

  • :phantomjs (String) - A custom path to the phantomjs executable
  • :debug (Boolean) - When true, debug output is logged to STDERR. Some debug info from the PhantomJS portion of Poltergeist is also output, but this goes to STDOUT due to technical limitations.
  • :logger (Object responding to puts) - When present, debug output is written to this object
  • :phantomjs_logger (IO object) - Where the STDOUT from PhantomJS is written to. This is where your console.log statements will show up. Default: STDOUT
  • :timeout (Numeric) - The number of seconds we'll wait for a response when communicating with PhantomJS. Default is 30.
  • :inspector (Boolean, String) - See 'Remote Debugging', above.
  • :js_errors (Boolean) - When false, JavaScript errors do not get re-raised in Ruby.
  • :window_size (Array) - The dimensions of the browser window in which to test, expressed as a 2-element array, e.g. [1024, 768]. Default: [1024, 768]
  • :screen_size (Array) - The dimensions the window size will be set to when Window#maximize is called. Expressed as a 2-element array, e.g. [1600, 1200]. Default: [1366, 768]
  • :phantomjs_options (Array) - Additional command line options to be passed to PhantomJS, e.g. ['--load-images=no', '--ignore-ssl-errors=yes']
  • :extensions (Array) - An array of JS files to be preloaded into the phantomjs browser. Useful for faking unsupported APIs.
  • :port (Fixnum) - The port which should be used to communicate with the PhantomJS process. Defaults to a random open port.
  • :host (String) - The name or IP of the PhantomJS host. Default is '127.0.0.1'.
  • :url_blacklist (Array) - Default session url blacklist - expressed as an array of strings to match against requested URLs.
  • :url_whitelist (Array) - Default session url whitelist - expressed as an array of strings to match against requested URLs.
  • :page_settings (Hash) - PhantomJS web page settings (http://phantomjs.org/api/webpage/property/settings.html).

URL Blacklisting & Whitelisting

Poltergeist supports URL blacklisting, which allows you to prevent scripts from running on designated domains:

page.driver.browser.url_blacklist = ['http://www.example.com']

and also URL whitelisting, which allows scripts to only run on designated domains:

page.driver.browser.url_whitelist = ['http://www.example.com']

If you are experiencing slower run times, consider creating a URL whitelist of domains that are essential or a blacklist of domains that are not essential, such as ad networks or analytics, to your testing environment.

Troubleshooting

Unfortunately, the nature of full-stack testing is that things can and do go wrong from time to time. This section aims to highlight a number of common problems and provide ideas about how you can work around them.

DeadClient errors

Sometimes PhantomJS crashes during a test. There are basically two kinds of crashes: those that can be reproduced every time, and those that occur sporadically and are not easily reproduced.

If your crash happens every time, you should read the PhantomJS crash reporting guide and file a bug against PhantomJS. Feel free to also file a bug against Poltergeist in case there are workarounds that can be implemented within Poltergeist. Also, if lots of Poltergeist users are experiencing the same crash then fixing it will move up the priority list.

If your crash is sporadic, there is less that can be done. Often these issues are very complicated and difficult to track down. It may be that the crash has already been fixed in a newer version of WebKit that will eventually find its way into PhantomJS. It's still worth reporting your bug against PhantomJS, but it's probably not worth filing a bug against Poltergeist as there's not much we can do.

If you experience sporadic crashes a lot, it may be worth configuring your CI to automatically re-run failing tests before reporting a failed build.

MouseEventFailed errors

When Poltergeist clicks on an element, rather than generating a DOM click event, it actually generates a "proper" click. This is much closer to what happens when a real user clicks on the page - but it means that Poltergeist must scroll the page to where the element is, and work out the correct co-ordinates to click. If the element is covered up by another element, the click will fail (this is a good thing - because your user won't be able to click a covered up element either).

Sometimes there can be issues with this behavior. If you have problems, it's worth taking screenshots of the page and trying to work out what's going on. If your click is failing, but you're not getting a MouseEventFailed error, then you can turn on the :debug option and look in the output to see what co-ordinates Poltergeist is using for the click. You can then cross-reference this with a screenshot to see if something is obviously wrong.

If you can't figure out what's going on and just want to work around the problem so you can get on with life, consider using a DOM click event. For example, if this code is failing:

click_button "Save"

Then try:

find_button("Save").trigger('click')

Timing problems

Sometimes tests pass and fail sporadically. This is often because there is some problem synchronising events properly. It's often straightforward to verify this by adding sleep statements into your test to allow sufficient time for the page to settle.

If you have these types of problems, read through the Capybara documentation on asynchronous JavaScript which explains the tools that Capybara provides for dealing with this.

Memory leak

If you run a few capybara sessions manually please make sure you've called session.driver.quit when you don't need session anymore. Forgetting about this causes memory leakage and your system's resources can be exhausted earlier than you may expect.

General troubleshooting hints

  • Configure Poltergeist with :debug turned on so you can see its communication with PhantomJS.
  • Take screenshots to figure out what the state of your page is when the problem occurs.
  • Use the remote web inspector in case it provides any useful insight
  • Consider downloading the Poltergeist source and using console.log debugging to figure out what's going on inside PhantomJS. (This will require an understanding of the Poltergeist source code and PhantomJS, so it's only for the committed!)

Filing a bug

If you can provide specific steps to reproduce your problem, or have specific information that might help other help you track down the problem, then please file a bug on Github.

Include as much information as possible. For example:

  • Specific steps to reproduce where possible (failing tests are even better)
  • The output obtained from running Poltergeist with :debug turned on
  • Screenshots
  • Stack traces if there are any Ruby on JavaScript exceptions generated
  • The Poltergeist and PhantomJS version numbers used
  • The operating system name and version used

Changes

Version history and a list of next-release features and fixes can be found in the changelog.

If you're viewing this at https://github.com/teampoltergeist/poltergeist, you're reading the documentation for the master branch. View documentation for the latest release (1.18.1).

Getting help

Questions should be posted on Stack Overflow, using the 'poltergeist' tag.

Bug reports should be posted on GitHub (and be sure to read the bug reporting guidance below).

Author: Teampoltergeist
Source Code: https://github.com/teampoltergeist/poltergeist 
License: MIT license

#ruby #driver 

野村  陽一

野村 陽一

1644901440

Seleniumのブラウザードライバーの概要

Seleniumのドライバーは、ブラウザーの自動化に不可欠です。Pythonまたはその他のプログラミング言語のSeleniumライブラリは、特定のブラウザーのドライバーを使用して、ブラウザーのアクションを制御し、ブラウザーに機能を追加し、その中のすべてのデータ(Webページ)を操作します。

最も一般的なブラウザのドライバを宣言する最も一般的な方法とは異なりますが、多くの場合、非互換性の問題が発生する可能性があります。PythonコードでWebドライバーをインストール、初期化する方法は複数あります(それほど一般的ではありません)。

ドライバーのダウンロード

Seleniumのエラーの最大のポイントは、ブラウザーのドライバーのバージョンがブラウザーのバージョンと一致しない場合に発生します。これにより、互換性の問題が発生します。そのため、まず、自動化に使用するWebブラウザ(Google Chrome、Mozilla Firefox、Apple Safariなど)と同じバージョンのドライバを常に使用する必要があります。

Webドライバーのダウンロードとインストールは完全に安全です。これらのドライバーは、公式ブラウザー会社によって維持され、ブラウザーとWebページのテストと自動化の目的でそれに応じて更新されるためです。

自動化するバージョンのブラウザを確認し、それに応じて以下のリファレンスからドライバをダウンロードしてください。

ウェブブラウザドライバーダウンロードリファレンス
Google Chrome / Chromiumダウンロード
Mozilla Firefoxダウンロード
マイクロソフトエッジダウンロード
アップルサファリすでに組み込まれています

ドライバーの使用方法

ここで、セレンWebドライバーの使用方法を見てみましょう。

1.直接の場所を入力する

  • ブラウザの自動化のためにPythonSeleniumコードでWebドライバーを使用するための最も一般的な方法。その人気の理由は、スクリプトでドライバーを定義するために使用する直接的なアプローチです。
  • この方法では、Webドライバーを手動でダウンロードする必要があります。

長所:長いセットアップや環境変数の把握を気にする必要がない
短所:コードの柔軟性が低下し、更新のたびに手動で変更される可能性があります

driver = webdriver.Chrome('path/to/chromedriver") 
driver = webdriver.Chrome('C://software/chromedriver.exe') #driver located at the specified location
driver = webdriver.Chrome('chromedriver.exe')  #driver located in the same directory as of the python script file
 
#other way
 
service = Service(executable_path="/path/to/chromedriver")
driver = webdriver.Chrome(service=service)

2.環境変数

  • 上記の方法を試した場合、コンピュータのディレクトリにインストールされているWebドライバの場所をメモ/記憶するのがいかに面倒であるかに気付いたかもしれません。
  • この問題に取り組むために、環境変数でドライバーの場所またはパスを定義します。定義が成功すると、コードでパスの場所を指定する必要がなくなり、簡単にコーディングできます。
  • この方法はパス変数の発行に使用されることをご存知かもしれませんが、この方法ではドライバーを手動でインストールする必要もあります。

利点:ドライバーへのパスを指定する手間がありません
欠点:更新機能がありません

環境パス変数を設定するには、コマンドプロンプトに移動し、次のコマンドを入力します。以下のコマンドの「C:\ WebDriver \ bin」の代わりに、ドライバーのパス(インストール場所)を使用します。

setx PATH "%PATH%;C:\WebDriver\bin"

この方法が難しい場合は、Windowsのスタートメニューで環境変数を検索し、[開く]-[システム環境変数の編集]をクリックしてください。その後、ポップアップウィンドウから「環境変数」を選択して、別のポップアップウィンドウを開きます。

[システム変数]オプションから[パスを開く]を選択し、[新規]をクリックして新しいパス変数を導入します。すべてのウィンドウで、Webドライバーの場所を貼り付けてから、[OK]、[OK]、[OK]、[OK]の順に貼り付けます。

環境変数環境変数

3.ドライバーマネージャー

最後に、おそらく最も便利な方法は、PythonコードのWebドライバーです。Webブラウザーで自動更新を選択すると、デバイスはブラウザーのみを更新し、インストールされているドライバーは更新しません。この場合、Pythonスクリプトの実行時に、コードはブラウザーとドライバーのバージョンが等しくない場合にエラーを出します。

長所:バージョンの互換性の問題がなく、複数のブラウザを簡単に切り替えることができます
短所:初心者向けに設定するのが少し難しいかもしれません

ドライバーマネージャーをインストールします

pip install webdriver-manager

マネージャーをインポートする

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager            # --> for Chrome
 
#from webdriver_manager.firefox import GeckoDriverManager               # --> for Firefox

これで、マネージャーをインストールしてインポートしたので、コードで次のように使用します–

このinstall() メソッドを使用して、マネージャーが使用する場所を取得し、それをloc_serviceクラスに渡します。このメソッドは、インストールされているWebドライバーの場所を自動的に通知します。

driver = webdriver.Chrome(ChromeDriverManager().install())   # --> for Chrome
 
#driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())     #--> for Firefox

その他のブラウザーについては、ドライバーマネージャーソフトウェアの公式GitHubリポジトリを確認できます。

結論

チュートリアルは以上です。SeleniumでWebドライバーを使用する一般的な方法とは異なり、このチュートリアルでは、同じことを実行するための他の、おそらく有利な方法について学習しました。  

リンク:https ://www.askpython.com/python-modules/introduction-browser-drivers-selenium

#python  #selenium 

Introducción A Los Controladores De Navegador En Selenium

Los controladores en Selenium son vitales y no imprescindibles para la automatización del navegador. La biblioteca Selenium en Python o en cualquier otro lenguaje de programación utiliza el controlador del navegador en particular para controlar los navegadores con sus acciones, agregarle funcionalidad y, en general, manipular los datos (página web) en él.

Al contrario de la forma más común de declarar el controlador de un navegador, que es la más común, pero a menudo puede dar lugar a problemas de incompatibilidad. Hay varias formas (no tan comunes) de instalar, inicializar controladores web en su código Python.

Descarga de los controladores

El principal punto de error en Selenium ocurre cuando la versión del controlador del navegador no coincide con la versión del navegador, por lo que surge un problema de compatibilidad. Entonces, para empezar, siempre debe usar el controlador con la misma versión que la del navegador web (Google Chrome, Mozilla Firefox, Apple Safari o cualquier otro) que pretende usar para la automatización.

Descargar e instalar controladores web es completamente seguro porque estos controladores son mantenidos por las empresas oficiales de navegadores y se actualizan en consecuencia, con fines de prueba y automatización de su navegador y páginas web.

Verifique con su navegador cuál tiene la intención de automatizar para su versión y descargue el controlador de las siguientes referencias en consecuencia:

Navegador webReferencia de descarga del controlador
Google Chrome/cromoDescargar
Mozilla FirefoxDescargar
Borde de MicrosoftDescargar
safari de manzanaYa incorporado

Maneras de usar los controladores

Veamos ahora cómo podemos usar los controladores web de selenio.

1. Ingresar la ubicación directa

  • El método más popular para usar un controlador web en el código Python Selenium para la automatización del navegador. La razón de su popularidad es el enfoque directo que utiliza para definir un controlador en un script.
  • Este método requiere la descarga manual del controlador web.

Ventaja : no hay necesidad de preocuparse por una configuración prolongada o descifrar la variable de entorno .
Desventaja : hace que el código sea menos flexible y esté sujeto a cambios manuales para cada actualización.

driver = webdriver.Chrome('path/to/chromedriver") 
driver = webdriver.Chrome('C://software/chromedriver.exe') #driver located at the specified location
driver = webdriver.Chrome('chromedriver.exe')  #driver located in the same directory as of the python script file
 
#other way
 
service = Service(executable_path="/path/to/chromedriver")
driver = webdriver.Chrome(service=service)

2. Variable de entorno

  • Si ha probado el método mencionado anteriormente, es posible que haya notado lo agotador que es anotar/recordar la ubicación de su controlador web instalado en algún directorio de su computadora.
  • Para abordar este problema, definimos la ubicación o ruta de nuestro controlador en Variable de entorno, de una vez por todas. Después de una definición exitosa, no necesitamos especificar la ubicación de la ruta en nuestro código y podemos codificar sin esfuerzo.
  • Este método también requiere la instalación manual del controlador, como sabrá, este método se usa para el problema de la variable de ruta.

Ventaja : no hay molestias de especificar la ruta al controlador
Desventaja : no hay funcionalidad de actualización

Para configurar la Variable de ruta del entorno, vaya a la línea de comandos y escriba el siguiente comando: En lugar de "C:\WebDriver\bin" en el siguiente comando, use la ruta (ubicación de instalación) del controlador.

setx PATH "%PATH%;C:\WebDriver\bin"

Si le resulta difícil esta forma, puede buscar la variable de entorno en el menú de inicio de Windows y hacer clic en Abrir: " Editar las variables de entorno del sistema ". Después de eso, desde la ventana emergente, seleccione " Variables de entorno " para abrir otra ventana emergente.

Desde la opción Variables del sistema , seleccione Ruta abierta y ahora haga clic en Nuevo para introducir una nueva variable de ruta. Pegue la ubicación de su controlador web en él, luego OK, OK, y finalmente OK nuevamente, en todas las ventanas.

Variable ambientalVariable ambiental

3. Administrador de controladores

El último método, y probablemente el más útil, es el Web Driver en su código Python. Al seleccionar, actualización automática en el navegador web, el dispositivo solo actualiza el navegador y no el controlador instalado, en este caso, al ejecutar el script de python, el código da error para versiones diferentes del navegador y el controlador.

Ventaja : no hay problemas de compatibilidad de versiones y ayuda a cambiar fácilmente entre varios navegadores .
Desventaja : tal vez un poco difícil de configurar para principiantes.

Instalar el administrador de controladores

pip install webdriver-manager

Importar el administrador

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager            # --> for Chrome
 
#from webdriver_manager.firefox import GeckoDriverManager               # --> for Firefox

Ahora que hemos instalado e importado el administrador, lo usamos en nuestro código como:

Utilice el install() método para obtener la ubicación utilizada por el administrador y pásela a una clase loc_service. Este método informa sobre la ubicación del controlador web instalado por sí mismo.

driver = webdriver.Chrome(ChromeDriverManager().install())   # --> for Chrome
 
#driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())     #--> for Firefox

Para cualquier otro navegador, puede consultar el repositorio oficial de GitHub del software del administrador de controladores.

Conclusión

Eso es todo por el tutorial. Al contrario de los métodos populares de uso de los controladores web en Selenium, en este tutorial aprendió sobre los otros y quizás ventajosos métodos para realizar lo mismo.  

Enlace: https://www.askpython.com/python-modules/introduction-browser-drivers-selenium

#python #selenium 

Servo Node

Servo Node

1621611746

How To Install A Device Driver On Linux- 2 Methods › Servo Node

Itching your head due to missing device driver on your machine? Looking for how to install a device drive on a Linux system? Just switched to a new OS, but hardware is not working well? Check out this article to learn how you can install a missing device drive on your Linux system.

Installing and configuring a driver on a Linux based machine is quite daunting for those who just switched to Linux from Windows/Mac, or trying the new OS with dual boot. The widely used windows and Mac operating system often makes it a user-friendly experience when it comes to install device drivers, but in case of a Linux OS, the user might find some of their hardware is not working. Well, this would not be an issue anymore.

Is it challenging to install a device driver on Linux?
For Windows and Mac OS users, it’s really an easy approach to install any device driver as the OS detects those automatically. Also, the users can download the missing ones from the internet, and just click on a simple wizard to have the driver installed.

However, in case of a Linux platform, the process is not enough simple. One of the most common reason is, Linux is an open-source OS and a number of variations available. So, there can’t be a single method that can suit all Linux platforms, and every of the distribution has its own way regarding how to install a device driver on system.

In addition, most of the default Linux drivers are open-source and integrated in the system, and this makes the installation of missing drivers quite complicated, if not included already with OS. Still, most of the useful drivers are automatically detected with popular Linux distros.

Another reason why installing a device driver on a Linux can be complicated is license policies which technically vary among Linux distributions. Such as Fedora restricts to include drivers which are legally prohibited or violate cyber laws. Even Ubuntu asks its users to prevent using closed hardware.

Means, installing a device driver on a Linux can be a bit challenging, but still here mentioned 2 approaches can be helpful.

Two Methods To Find Drivers & Install on Linux
Approach 1: Using Built-in Interface
Approach 2: Using Command Line

#install linux driver #linux driver install #how to install linux driver