By Zac Campbell
If you’ve used Selenium you may have found that it’s difficult to interact with elements that are in the browser itself, like download prompts and so forth. With Firefox OS things are different. Marionette, our test harness, lets us traverse up and down between the system and webapp. If you’re familiar with the architecture of Firefox you’ll know this as the browser chrome and content respectively.
Fortunate, too, because in Firefox OS there are some additional system prompts like <select> boxes that are shown at the system level. The reason this is done is to present to the user a usable list of options on the small screen mobile device. You might have seen this behaviour already on iOS and Android devices if you own one.
What’s happening in this example is this;
1. Firefox OS’s System is detecting that the user has tapped on the <select> box inside the Settings web app.
2. The system copies all of the options in the box and inserts them into a <ol> element at the system level.
3. The <ol> element is then shown to the user with the ‘OK’ box button
4. After the user has selected their option, Firefox OS feeds the user’s selection back to the web app.
To interact with this system box using Marionette we need to do some frame switching from the Settings app into the System app! I covered this in detail in part 2 of the blog series.
An important point to note is that the locator for the <select> box in the web app will be different in the System app because the System app compiles its own HTML. The common links between them are the number of options and the text value of the option. Thus in our code we will locate the option using the element’s text value.
The workflow for achieving this in our test is:
1. Switch back to the System app
2. Find the HTML locator for the list item
3. Click the list item to choose it
4. Find the HTML locator for the OK button
5. Click OK
6. Switch frame into the web app then resume the test steps.
Here is the HTML in the system app for the example:
<section id="value-selector-container"> <h1 data-l10n-id="choose-option"> Select </h1> <ol role="listbox"> <!-- snip --> <li aria-checked="true" data-option-index="23"> <label for="gaia-option-23"><span>London</span></label> </li> <li data-option-index="24"> <label for="gaia-option-24"><span>Luxembourg</span></label> </li> <li data-option-index="25"> <label for="gaia-option-25"><span>Madrid</span></label> </li> <!-- snip --> </ol> </section>
Now here’s how we’ll write the test to select the option box:
# Switch back to System frame self.marionette.switch_to_frame() # Find the ‘Madrid’ <li> using an Xpath locator # Marionette’s implicit wait will wait for Gaia to create it list_item = self.marionette.find_element("xpath", "//section[@id='value-selector-container']//li[label[span[text()='%s']]]" % 'Madrid') # Click the list item list_item.click() # Now find and click ‘OK’ close_button = self.marionette.find_element('css selector', 'button.value-option-confirm') close_button.click() # Find and switch back to the Settings app frame settings_frame = self.marionette.find_element(*settings_frame_locator) self.marionette.switch_to_frame(settings_frame) # OK now we’re back in the Settings app the test can continue
You may like to create a wrapper method for this to save yourself some duplication.
We can access all sorts of system dialogs in Firefox OS like notifications (that slide out from the status bar), app install notifications, alert boxes, lockscreens and so forth.
With Firefox OS and Marionette we have great powers to automate end-to-end testing and integration between the operating system and webapp content.