{"id":131,"date":"2013-02-13T17:33:42","date_gmt":"2013-02-13T17:33:42","guid":{"rendered":"http:\/\/blog.mozilla.org\/webqa\/?p=131"},"modified":"2013-02-13T17:33:42","modified_gmt":"2013-02-13T17:33:42","slug":"part-2-ui-testing-on-firefox-os-working-with-iframes","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/fxtesteng\/2013\/02\/13\/part-2-ui-testing-on-firefox-os-working-with-iframes\/","title":{"rendered":"Part 2: UI Testing on Firefox OS. Working with iframes"},"content":{"rendered":"<p>by Zac Campbell<\/p>\n<p>In Part 2 we\u2019ll talk about how Firefox OS uses the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/HTML\/Element\/iframe\" target=\"_blank\">iframe<\/a> HTML element for displaying apps. This behaviour is quite different to a typical webpage.<\/p>\n<p>If you\u2019ve already used Firefox OS thus far then you\u2019ll realise that it is a web browser on your phone. To take it to the next level, Firefox OS is one big web page, in a web browser on your phone.<\/p>\n<p>On a desktop computer you open each webpage or a web app in a different window or tab. On Firefox OS each web app will be opened in a new iframe. This is good for security &#8211; it \u2018sandboxes\u2019 apps &#8211; but it can be a bother for testing. We need to switch between the iframes depending upon which app we need to be testing at that time.<\/p>\n<p>This frame switching functionality exists in desktop variation of web pages and is supported by WebDriver, however it is rarely used. The user and design requirements of Firefox OS mean that iframes are about to undergo a resurrection!<\/p>\n<p><a href=\"http:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_cal.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-141\" alt=\"Firefox OS Calendar frame\" src=\"http:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_cal-300x223.jpg\" width=\"300\" height=\"223\" srcset=\"https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_cal-300x223.jpg 300w, https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_cal-600x446.jpg 600w, https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_cal.jpg 734w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>This diagram depicts the Calendar app loaded inside Firefox OS. The Calendar app iframe is a child of the Firefox OS system frame. In this basic example we want to run tests against the Calendar. After the app is loaded, we\u2019ll need to instruct marionette to switch into it before we can find and interact with its elements:<br \/>\n<code><br \/>\n# The Calendar app is already running<br \/>\n# Now we are in the System level frame<br \/>\n# Let\u2019s find the Calendar frame<br \/>\ncalendar_frame = self.marionette.find_element(\u2018css selector\u2019,<br \/>\n\u201ciframe[src=app:\/\/calendar.gaiamobile.org\/index.html]\u201c)<br \/>\n# OK we\u2019ve got the frame; now let\u2019s switch into it.<br \/>\n# We can pass in the HTMLElement<br \/>\nself.marionette.switch_to_frame(calendar_frame)<br \/>\n# Let\u2019s check the title<br \/>\nprint self.marionette.title<br \/>\n<i>Calendar<\/i><br \/>\n# Ready to run the test!<br \/>\n<\/code><\/p>\n<p>That wasn\u2019t too bad! Now let\u2019s look at a couple more examples the Mozilla Web QA team have experienced while developing automated UI tests for Firefox OS.<\/p>\n<p><a href=\"http:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_browser.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-140\" alt=\"Firefox OS Browser frame\" src=\"http:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_browser-300x223.jpg\" width=\"300\" height=\"223\" srcset=\"https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_browser-300x223.jpg 300w, https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_browser-600x446.jpg 600w, https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_browser.jpg 734w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>In this example diagram the app we are using is the Browser within Firefox. You may come across this example if you are using the Browser to test how your website will appear in the Firefox OS Browser.<\/p>\n<p>The tricky part of this example is that there is another &lt;iframe&gt; nested inside the Browser itself and that is what contains the displayed website.<\/p>\n<p>To access the URL bar, Go button and other browser-related interfaces we need to be in the Browser\u2019s frame (the middle frame).<\/p>\n<p>In this code example we\u2019ll switch into the Browser, type in the URL bar, load the webpage then finally switch into the page iframe so we can read the webpage content.<br \/>\n<code><br \/>\n# The Browser app is already running<br \/>\n# Let\u2019s find the Browser frame<br \/>\nbrowser_frame = self.marionette.find_element(\u2018css selector\u2019,<br \/>\n\u201ciframe[src=app:\/\/browser.gaiamobile.org\/index.html]\u201c)<br \/>\n# OK we\u2019ve got the frame; now let\u2019s switch into it.<br \/>\nself.marionette.switch_to_frame(browser_frame)<br \/>\n# Find the URL bar and insert a URL<br \/>\nurl_bar = self.marionette.find_element(\u2018id\u2019, \u2018url-input\u2019)<br \/>\nurl_bar.send_keys(\u2018https:\/\/www.mozilla.org\u2019)<br \/>\n# Click the \u2018go\u2019 arrow and wait for the page to load<br \/>\nself.marionette.find_element(\u2018id\u2019, \u2018url-button\u2019).single_tap()<br \/>\ntime.sleep(10)<br \/>\n# The page has loaded so we\u2019ll switch into the frame<br \/>\n# where we can view the HTML<br \/>\nwebpage_frame = self.marionette.find_element(\u2018css selector\u2019,<br \/>\n\u2018iframe.browser-tab\u2019)<br \/>\nself.marionette.switch_to_frame(webpage_frame)<br \/>\n# Now let\u2019s check the title again<br \/>\nprint self.marionette.title<br \/>\n<i>Mozilla \u2014 Home of the Mozilla Project \u2014 mozilla.org<\/i><br \/>\n<\/code><br \/>\nPhew, getting a bit trickier now with various layers to traverse! Now you\u2019re in the website\u2019s frame and can click links, get text and functionally test the site in the manner you\u2019re familiar with from WebDriver.<\/p>\n<p>In my final example I\u2019ll switch to the keyboard UI to type an SMS message. This is a good example of how the system frames (as the keyboard is part of the operating system) and the app frames co-exist.<\/p>\n<p><a href=\"http:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_keyboard.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-142\" alt=\"Firefox OS Keyboard frame\" src=\"http:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_keyboard-300x223.jpg\" width=\"300\" height=\"223\" srcset=\"https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_keyboard-300x223.jpg 300w, https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_keyboard-600x446.jpg 600w, https:\/\/blog.mozilla.org\/fxtesteng\/files\/2013\/02\/fxos_pt1_keyboard.jpg 734w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>This test will load the SMS app and focus in the input message field, at which point Firefox OS will open the keyboard for you to type into the field (just imagine doing this as a user). However this test contains an important difference &#8211; when we switch to the Keyboard frame we want to do it without Firefox OS knowing. Otherwise, as the SMS app loses its focus the keyboard will close! Thus when we switch to the Keyboard frame we pass in focus=False which skips sending the focus event to Firefox OS. It will make sense in the example!<\/p>\n<p><code><br \/>\n# The SMS app is already loaded<br \/>\n# Let\u2019s find its frame<br \/>\nsms_frame = self.marionette.find_element(\u2018css selector\u2019,<br \/>\n\u201ciframe[src=app:\/\/sms.gaiamobile.org\/index.html]\u201c)<br \/>\n# OK we\u2019ve got the frame; now let\u2019s switch into it.<br \/>\nself.marionette.switch_to_frame(sms_frame)<br \/>\n# Tap\/click \u2018+\u2019 to start writing a new message<br \/>\nself.marionette.find_element(\u2018id\u2019, \u2018icon-add\u2019).single_tap()<br \/>\n# Focussing into the SMS field will cause the Keyboard to pop open<br \/>\nself.marionette.find_element(\u2018id\u2019, \u2018receiver-input\u2019).single_tap()<br \/>\n# Now we need to traverse up to the system frame<br \/>\n# and then back down into the Keyboard<br \/>\n# If we want to go to the system frame we use empty switch_to_frame<br \/>\nself.marionette.switch_to_frame()<br \/>\nkeyboard_frame = self.marionette.find_element(\u2018css selector\u2019,<br \/>\n\u2018#keyboard-frame iframe\u2019)<br \/>\n# The important bit: switch to the Keyboard without focus!<br \/>\nself.marionette.switch_to_frame(keyboard_frame, focus=False)<br \/>\n<\/code><br \/>\nThat\u2019s it, now we\u2019re in the keyboard frame. We can find the buttons, tap them and the key presses will be sent to the SMS app.<\/p>\n<p>When you want to go back to the SMS app you will need to switch back up the iframe tree to the System frame then back down into the SMS app. The code can get long and tedious so try and keep your test cases short and simple.<\/p>\n<p><i>NB: In everyday use you are more likely to use Marionette\u2019s send_keys(), but just in case you have a need to type with the keyboard this is how you would do it!<\/i><\/p>\n<p>As with all things in the world the best way to learn is to get out there and try it out yourself.<\/p>\n<p>Next blog we\u2019ll look at how Firefox OS apps are designed differently; instead of loading individual pages they use Ajax and CSS to change what visible in the viewport.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>by Zac Campbell In Part 2 we\u2019ll talk about how Firefox OS uses the iframe HTML element for displaying apps. This behaviour is quite different to a typical webpage. If &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/fxtesteng\/2013\/02\/13\/part-2-ui-testing-on-firefox-os-working-with-iframes\/\">Read more<\/a><\/p>\n","protected":false},"author":1359,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24660],"tags":[4261,24660,31333,27793,31334,25193],"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/posts\/131"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/users\/1359"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/comments?post=131"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/posts\/131\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/media?parent=131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/categories?post=131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/fxtesteng\/wp-json\/wp\/v2\/tags?post=131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}