Selenium Flashcards
What do you do if your automation scripts fail?
First thing I’d do, is ask: why are they failing?
If they are failing because of a framework/test script error.
See: debugging.
If they are failing because of an application error.
See: report the issue by filing a bug, raising flags, etc.
What are desired capabilities?
WebDriver instance features, for example:
browser name, version, platform, javascript enabled, database enabled, accept ssl certificates, proxy use, using profiles.
Grid-specific ones: selenium protocol, max instances
How would you go about writing an automated test?
Good automated tests are easily transferred from good bug reports or test cases from a test case repository.
This isn’t true of every test case – for example usability issues or minor cosmetic issues. Traceability.
I might go through and manually run through the test, writing out my steps in the form of comments.
Then I’d start translating that to code, testing each piece as I wrote it.
If there’s existing automated tests and a framework in place, I’d spend some time looking at those — finding out what’s available to me. If they’re using PageObjects, I’ll see if the page I’m testing has methods or queries I can use.
Main tools: Firebug / Firepath, DevTools, IRB, Ruby, some JavaScript … (sometimes IDE/Builder).
Using Ruby console scripts with helper methods in IRB to test snippets and ideas.
Inspect the DOM tree and look at the elements for selectable attributes.
Ask some immediate questions - “is this a unique element selector?” Or will I have to traverse the DOM to find it?
I might get a collection of elements and then select by index.
For example, getting the first link: grab the <ul> by class, then do ul.findElements.By.TagName(“a”)[0].
Or if its nested tables, I might have to grab the parent table and iterate through them, or use XPath.
I know you guys use a lot of Java, I know of BeanShell, which I understand is embeddable and can execute Java at and interact with APIs at runtime (maybe similar to Pry or ByeBug). Groovy is something else I’ve heard of - dynamic like Ruby?
Technologies are just tools. What to do with those tools is transferrable.
I’ve also used JavaScript for automating a Node app using NightwatchJS.
I’ve used a variety of IDEs — Sublime, VS Code, Xamarin Community, Eclipse, Xcode…
Debugging
For example, Selenium JSON wire protocol is language and platform independent. Tailing driver logs, server logs, using binding statements (if Ruby), etc.
</ul>
How would you deal with AJAX asynchronous elements?
clickAndWait will execute the command and wait for a response/navigation render
Use a WebDriver::Wait object — wait.until to appear, put it in a begin/rescue block and retry a couple times before failing.
begin tries ||= 3, rescue retry if (tries -= 1) > 0
If the step isn’t crucial, might use a verification instead of an assert so the test continues to run but it’s reported.
What are implicit waits? What are explicit waits?
Implicit waits set a default wait time between expression execution.
So when you set it on the driver instance, it’ll tell the driver to continuously poll the DOM frequently for x seconds when trying to locate elements, or else throw an exception (NoSuchElementException).
You can set a default in the driver set up, and you can alter it in your code at certain points.
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
In explicit wait, you define some conditional code block (or some lambda expression in C#) and tell the driver to wait UNTIL some Expected Condition returns before continuing execution:
# WebDriverWait class wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds begin tries ||= 3 element = wait.until { driver.find_element(:id => "some-dynamic-element") } rescue retry if (tries -= 1) > 0 ensure driver.quit end
There’s a lot of convenience helper methods for common expected conditions…element_to_be_clickable, element_is_visible, alert_is_present, presence_of_nested_elements, etc. (http://www.aptuz.com/blog/selenium-implicit-vs-explicit-waits/)
The problem: explicit waits throw an exception.
Benefit: explicit wait is extendable. You can write any condition you’d like. I would typically write this code in a Driver/Browser class, and then call it like Driver.Wait() in my tests. This way I can have tailored wait conditions for specific scenarios. This is also helpful for logging.
Example: # nested elements wait.until do driver.find_elements(id: ‘id').size > 0 end
Why use explicit waits as opposed to implicit waits?
Implicit waits are useful, but they have overhead. They can slow things down. Also, what if a particular object takes 5 minutes to load and we know it will? (mail_in workflow)
Explicit waits can call out when something is dynamic and shouldn’t be available right away, and when it SHOULD be available, I want to fail fast.
For example, if I want to send_keys to a search box and then click the search button, I don’t need to wait for that button to appear — it should be immediately available, and I want to know when its not.
The first time I used explicit wait was just putting a bunch of sleep 5 in my code. It’s awful, but it does draw out the explicitness of it.
Mixing them on the same driver instance can cause competing wait logic — unpredictable wait times.
I.e., when Explicit > Implicit, the max time taken by the driver will be Explicit. When Implicit > Explicit, the time varies (could be Implicit Max + Explicit, could change with driver implementations.
Explicit waits are defined explicitly in the code. Implicit waits could be defined in multiple locations — If you’re running on a remote server, or through a proxy on the grid. It becomes difficult to track down.
But you COULD set a small default implicit wait (1-2 seconds), and then disable them for element_is_present checks, so that they’ll fail fast.
What are some ways to locate elements on a page?
Class name
CSS selector (browser.div_element(class: “class”))
ID - preferred method, most absolute
LinkText
Name
Partial Link Text (i.e., with some-text*)
TagName
XPath - usually a last attempt, almost always available (very customizable, looking for presence or absence of values, indexes of particular elements) I can use browser.text_field(xpath: ‘.//…’), then get its attributes.
Again, I’d check the framework and existing tests to see if these methods have already been streamlined for me. Typically, query methods are defined in the PageObjects.
How can you ensure elements are visible before operating on them?
Use boolean checks is_displayed, is_selected, is_enabled, etc. You can either assert on these or define explicit waits.
What would you do to help with element selection - if you were having problems?
Work directly with developers to design testable code - unique IDs, clear syntax, clean code (no unnecessary divs in legacy code - i.e., if the display: none).
I could play around with this myself in DevTools, adding attributes directly to elements and making sure I can find them in the DOM.
At Comcast, we used Calabash which operates similar to Selenium. It uses Accessibility Labels (iOS) and Resource IDs (Android) to locate elements. These are fairly easy to add in Xcode. So what we would do is we’d compile a list of where we wanted to see Accessibility Labels, and then when we had a few, we’d just add them ourselves and submit a pull request. The branch was outside master any way with the addition of the calabash.framework injection.
What are some driver navigation methods?
All defined on the Watir::Browser object:
goto, back, close, quit, refresh, screenshot…
What are some methods for manipulating/selecting more advanced elements?
WebDriver.Support classes have a lot of wrappers for common HTML elements (e.g., Select).
If it comes down to it, injecting JS by forcing an event to fire or defining a new listener, or setting some variable to true, or setting CSS display property, etc.
How would you handle multiple frames or windows?
Select frame by id
browser. window(:title => /known part of title/).use { # block }
browser. windows[0] # get by index
How would you handle popups?
browser.window(title: /Blog/) { #execute block }
May have to iterate over children windows
For JS alerts: browser.alert.exists? browser.alert.text; browser.alert.ok; browser.alert.close
JS alerts, confirms, prompts all have methods.
When in doubt, browser.execute_script(“window.prompt = function() { return null; }”)
How could we handle menu selection boxes that don’t behave like normal select boxes?
Typically hover, so
browser.action.move_to(browser.find_element(id: “id”))).perform
Last ditch effort I could just inject some JS that changes the CSS property to visible or display or :hover pseudo-selector.
Often action methods expect Selenium element, so I might have to build an action up like:
watir_element = browser.div browser.driver.action #=> Selenium::WebDriver::ActionBuilder .key_down(:shift) .click(watir_element.wd) .key_up(:shift) .perform
What is the difference between assert and verify?
Both check whether a given condition is true/false.
For assertions, if the condition is false, test execution halts. Useful when you know the rest of the test suite is useless without this condition passing.
For verification, test execution continues.