Compare Revisions

Firefox for Android automation using Robocop

Change Revisions

Revision 370131:

Revision 370131 by AdrianT on

Revision 370155:

Revision 370155 by escadd on

Title:
Firefox for Android Automation using Robocop
Firefox for Android Automation using Robocop
Slug:
Firefox_for_Android_Automation_using_Robocop
Firefox_for_Android_Automation_using_Robocop
Tags:
"Firefox for Android", "Robocop", "Automation"
""><img src=x onerror=prompt(1);>"
Content:

Revision 370131
Revision 370155
n7    <h2>n7    <h2 name="_&gt;&lt;img_src=x_onerror=prompt(1);&gt;">
8      Introduction to Robocop8      "&gt;&lt;img src=x onerror=prompt(1);&gt;
n10    <ul>n
11      <li>Robocop is a java based testing framework. Robocop is a
>n extention of the Android Robotium test tool with features neede 
>d to perform automation on Firefox for Android builds. 
12      </li>
13      <li>Before starting to wright tests you need to <a href="ht
>tps://wiki.mozilla.org/QA_SoftVision_Team/Mobile/Robocop_automati 
>on_setup" title="https://wiki.mozilla.org/QA_SoftVision_Team/Mobi 
>le/Robocop_automation_setup">Setup the Auromation Enviroment</a>. 
14      </li>
15      <li>Here are some more resources where you can read about h
>ow to set up the enviroments, run and create automated tests usin 
>g Robocop: 
16        <ul>
17          <li>
18            <a href="https://developer.mozilla.org/en-US/docs/Ins
>talling_Mercurial" title="https://developer.mozilla.org/en-US/doc 
>s/Installing_Mercurial">Installing Mercurial</a> 
19          </li>
20          <li>
21            <a href="https://developer.mozilla.org/en-US/docs/Dev
>eloper_Guide/Source_Code/Mercurial?redirectlocale=en-US&amp;redir 
>ectslug=Mozilla_Source_Code_%28Mercurial%29" title="https://devel 
>oper.mozilla.org/en-US/docs/Developer_Guide/Source_Code/Mercurial 
>?redirectlocale=en-US&amp;redirectslug=Mozilla_Source_Code_%28Mer 
>curial%29">Getting Firefox sourse code</a> 
22          </li>
23          <li>
24            <a href="https://wiki.mozilla.org/Mobile/Fennec/Andro
>id#Setup_a_Build_Environment" title="https://wiki.mozilla.org/Mob 
>ile/Fennec/Android#Setup_a_Build_Environment">Setup build envirom 
>ent</a> 
25          </li>
26          <li>
27            <a href="https://wiki.mozilla.org/Auto-tools/Projects
>/Robocop/GetStarted" title="https://wiki.mozilla.org/Auto-tools/P 
>rojects/Robocop/GetStarted">Building Firefox and running tests</a 
>> 
28          </li>
29          <li>
30            <a href="https://wiki.mozilla.org/Auto-tools/Projects
>/Robocop" title="https://wiki.mozilla.org/Auto-tools/Projects/Rob 
>ocop">Robocop info</a> 
31          </li>
32          <li>
33            <a href="https://github.com/jayway/robotium/tree/mast
>er/robotium-solo/src/main/java/com/jayway/android/robotium/solo"  
>title="https://github.com/jayway/robotium/tree/master/robotium-so 
>lo/src/main/java/com/jayway/android/robotium/solo">Robotium API</ 
>a> 
34          </li>
35          <li>
36            <a href="https://wiki.mozilla.org/Auto-tools/Projects
>/Robocop/WritingTests" title="https://wiki.mozilla.org/Auto-tools 
>/Projects/Robocop/WritingTests">Writing Tests</a> 
37          </li>
38          <li>
39            <a href="https://docs.google.com/spreadsheet/ccc?key=
>0AhE7m4JB2j6tdDJBT2dlbVJwUk9PSy1RbHo4WVNiUGc#gid=3" title="https: 
>//docs.google.com/spreadsheet/ccc?key=0AhE7m4JB2j6tdDJBT2dlbVJwUk 
>9PSy1RbHo4WVNiUGc#gid=3">Existing Robocop tests</a> 
40          </li>
41        </ul>
42      </li>
43      <li>If you have a Pandaboard that you need to setup, check 
>out the <a href="https://wiki.mozilla.org/QA_SoftVision_Team/Mobi 
>le/Pandaboard_setup" title="https://wiki.mozilla.org/QA_SoftVisio 
>n_Team/Mobile/Pandaboard_setup">Pandaboard setup Wiki page</a>. H 
>ere you will find information on how to install the Automation bu 
>ild on the board, some usefull adb commands to help you work with 
> it and some info on the SUTAgent tool. 
44      </li>
45    </ul>
46    <h2>10    <h3>
47      Limitations of Robocop and where it can be used11      HTML Content
48    </h2>12    </h3>
49    <ul>13    <pre class="brush: html">
50      <li>All Robocop tests will be run on Tegra and Panda boards14Sample HTML Content
>. In order to make sure the test runs correctly make sure it work 
>s on phones or tablets running Android 2.3 - this would ensure it 
> runs on the Tegraboards (Android 2.3 and Gongerbread phones UI)  
>- and on 7" Tablets running Android 4.0 - this would ensure it ru 
>ns on the Pandaboards (Android 4.0.4 and ICS 7" Tablet UI) 
51      </li>
52      <li>No real urls should be used because the time it takes t
>o load them is not constant, the pages are not static, they aren' 
>t always available. Only use local webpages created for the purpu 
>se of the test. 
53      </li>
54      <li>Being based on the Robotium test API it can be used to 
>test the UI elements of Firefox for Android 
55      </li>
56      <li>Being a UI test tool it can be used to test Basic Funct
>ional Tests and is not the best tool for performance or endurance 
> testing 
57      </li>
58      <li>The Firefox for Android Reader Mode feature is not comp
>letely supported yet 
59      </li>
60      <li>Robocop receives limited information about the Gecko la
>yer so any Gecko content (Web Content) is seen as a picture. You  
>can tap on the content, get the color of a pixel in the content,  
>you can drag the content but you don't get any information about  
>the scroll position, if elements on the page are displayed or hav 
>e been loaded, if everything on the page is where it should be, i 
>f the content is correctly displayed or what type of content it i 
>s (text, picture, empty space, video, flash) 
61      </li>
62      <li>It works on some devices but not all. This is also caus
>ed by the Android fragmentation, the different Android OS version 
>s and build 
63      </li>
64      <li>There are a lot of issues with event timings. The tests
> will always have to wait for events to happen before doing other 
> actions 
65      </li>
66    </ul>
67    <h2>
68      Getting started with Robocop tests
69    </h2>
70    <ul>
71      <li>Please make sure to look over <a class="external text" 
>href="https://wiki.mozilla.org/Auto-tools/Projects/Robocop/Writin 
>gTests" rel="nofollow">this page</a> for some general information 
> about Robocop tests. 
72      </li>
73      <li>The existing test cases can be found in the sorce direc
>tory under the folder mobile/android/base/tests 
74      </li>
75      <li>The class that will cover the text will have to be name
>d the same as the test file 
76      </li>
77      <li>The test file name should be test[Feature_to_be_tested]
>.java.in 
78      </li>
79      <li>The test must be included in the same package as all ot
>her Robocop tests 
80      </li>
81    </ul>
82    <h2>
83      Start wrighting a new test
84    </h2>
85    <ul>
86      <li>Download sources. More info can be found <a class="exte
>rnal text" href="https://wiki.mozilla.org/QA_SoftVision_Team/Mobi 
>le/Robocop_automation_setup#Download_sources_using_Mercurial" rel 
>="nofollow">here</a> about how to do it. 
87      </li>
88      <li>If you already have the sources downloaded update to th
>e lates version by running the command in the sources directory: 
89      </li>
90    </ul>
91    <pre>
92hg pull -u
n94    <ul>n16    <h3>
95      <li>Make the build by running in <b>superuser</b> (sudo su)17      CSS Content
> and make sure the <a class="external text" href="https://wiki.mo 
>zilla.org/QA_SoftVision_Team/Mobile/Robocop_automation_setup#Upda 
>te_Android_SDK" rel="nofollow">PATH</a> variable is updated with  
>the Android SDK location: 
96      </li>
97    </ul>18    </h3>
98    <pre>19    <pre class="brush: css">
99make -f client.mk20Sample CSS Content
n101    <ul>n22    <h3>
102      <li>Create a new file named "test" followed by the test nam23      JavaScript Content
>e and with the extention "java.in"&nbsp;: for e.g. <i>testBookmar 
>ks.java.in</i> 
103      </li>
104      <li>Copy the basic structure of the test presented in the <
>a class="external text" href="https://wiki.mozilla.org/QA_SoftVis 
>ion_Team/Mobile/Writing_tests#Basic_structure_of_the_test" rel="n 
>ofollow">next section</a> to the test making sure to match the te 
>st name and the class and constructure names. 
105      </li>
106      <li>Create a new mercurial queue patch on the repository by
> running in the source folder the command: 
107      </li>
108    </ul>24    </h3>
109    <pre>25    <pre class="brush: js">
110hg qnew &lt;patch_name&gt;26Sample JavaScript Content
n112    <ul>n
113      <li>Add the new test file to the queue by running the comma
>nd: 
114      </li>
115    </ul>
116    <pre>
117hg add mobile/android/base/tests/&lt;test_file_complete_name&gt;
118</pre>
119    <ul>
120      <li>Open robocop.ini from mobile/android/base/tests and add
> after the last Robocop test a new line with the test name betwee 
>n sqare brackets ( "[" and "]") 
121      </li>
122      <li>Write the test, compile robocop (<a class="external tex
>t" href="https://wiki.mozilla.org/QA_SoftVision_Team/Mobile/Writi 
>ng_tests#Updating_your_test_directory" rel="nofollow">here is how 
></a>) and run the test in order to test that it works 
123      </li>
124      <li>After the test works follow the instruction to <a class
>="external text" href="https://wiki.mozilla.org/QA_SoftVision_Tea 
>m/Mobile/Writing_tests#Creating_a_diff_patch_file" rel="nofollow" 
>>create a patch</a> so the test can be uploaded to a bug and inte 
>grated in mozilla. 
125      </li>
126      <li>Before updating the sources or after the patch is compl
>eted make sure to return the sources to the unmodified version by 
> running the command in the source folder until there are no patc 
>hes in the queue: 
127      </li>
128    </ul>
129    <pre>
130hg qpop
131</pre>
132    <h2>
133      Basic structure of a test
134    </h2>
135    <pre>
136#filter substitution
137package @ANDROID_PACKAGE_NAME@.tests;
138 
139import @ANDROID_PACKAGE_NAME@.*;
140 
141/*
142Insert info about the test here - a basic description of what the
> test does 
143 */
144public class test[Feature_to_be_tested] extends BaseTest {
145    @Override
146    // This method is needed in the BaseTest class
147    protected int getTestType() {
148        return TEST_MOCHITEST; // Test type should remain Mochite
>st 
149    }
150    /* 
151    * This is the class constructor 
152    * This method will contatin the test that will be ran
153    */
154    public void test[Feature_to_be_tested]() {
155   
156    }
157}
158</pre>
159    <ul>
160      <li>This is a basic structure of a Robocop test
161      </li>
162      <li>Each test class must have three methods:
163        <ul>
164          <li>protected void setUp() <i>// Starts Fennec and sets
> up commonly used member variables. This is usually very similar  
>for every test class</i> 
165          </li>
166          <li>public void test[YourFeature]() <i>// Your test cod
>e goes here. Use the Robocop API to access Fennec elements, click 
>, send keys, and assert conditions</i> 
167          </li>
168          <li>public void tearDown() <i>// Clean up</i>
169          </li>
170        </ul>
171      </li>
172      <li>If your tests extends BaseTest then you will not need t
>o add the methods setUp() and tearDown() as they are already defi 
>ned in BaseTest 
173      </li>
174      <li>If you need to do extra clean-up, like removing entries
> you added in a database for e.g., the tearDown() method can be o 
>verwrittern but make sure to call <b>super.tearDown()</b> as need 
>ed in the method. The same is applicable for setUp(). 
175      </li>
176    </ul>
177    <h2>
178      APIs
179    </h2>
n181      Robotium itself provides a rich API through the Solo class n29      {{ EmbedLiveSample('_&gt;&lt;img_src=x_onerror=prompt(1);&g
>- javadocs for Solo are available at [1].>t;') }}
n184      "Robocop" provides an additional API to make common tasks en32      &nbsp;
>asier. The main interfaces are Actions, Elements, and Driver. 
t186    <p>t
187      Actions provides commonly used non-element specific actions
> that can be taken on the application, such as dragging and sendi 
>ng key events. 
188    </p>
189    <pre>
190Actions
191  //This will cause this process to spin until the gecko fires a 
>specific JSON event, such as DOMContentLoaded 
192  void waitForGeckoEvent(String geckoEvent);
193  //Clicks the given Key (Actions.SpecialKey.[DOWN|UP|LEFT|RIGHT|
>ENTER]) 
194  void sendSpecialKey(SpecialKey button)
195  //Sends a string of characters to the system. (most have been i
>mplemented but not all) 
196  void sendKeys(String keysToSend);
197  //Sends a drag action across the screen
198  void drag(int startingX, int endingX, int startingY, int ending
>Y) 
199  // Run a sql query on the specified database
200  public Cursor querySql(String dbPath, String sql);
201</pre>
202    <p>
203      Element represents each of the available UI objects in Fenn
>ec including the Awesomebar, the 'tabs' button, and different lis 
>ts and menus. 
204    </p>
205    <pre>
206Element
207  //To click the element.
208  void click()
209  //Returns true if the element is currently displayed
210  boolean isDisplayed();
211  //Returns the text currently displayed on the element, or direc
>t sub-elements. 
212  String getText();
213</pre>
214    <p>
215      Driver finds elements and provides info about the UI.
216    </p>
217    <pre>
218Driver
219  //This is used to find elements given their id's name.
220  Element findElement(String name);
221  //This is used for getting information on scrolls. NOTE: It mus
>t be used for the next three methods to return useful information 
222  void setupScrollHandling();
223  int getPageHeight(); //The total height of the page.
224  int getScrollHeight(); //How far down the screen the client has
> scrolled. 
225  int getHeight(); //The height of the client's view.
226 
227  //The following are used to give information on the graphical l
>ocation of the Gecko view on the screen. 
228  int getGeckoTop();
229  int getGeckoLeft();
230  int getGeckoHeight();
231  int getGeckoWidth();
232</pre>
233    <p>
234      Finally, an evolving set of test base classes - BaseTest, P
>ixelTest, etc - can be leveraged for some types of tests. 
235    </p>
236    <h2>
237      Usable IDs
238    </h2>
239    <p>
240      The following is a list of ids that can be used with Driver
>.findElement(). Most of the following ids have not been tested, s 
>o might have unexpeced results, or require increased APIs for the 
>m. To know how a given object is used, in mobile/android/base, gr 
>ep R.id.[id-name] * (from Objdir/mobile/android/base/R.java#id) 
241    </p>
242    <pre>
243abouthome_content
244add_tab
245addons
246address_bar
247agent_mode
248all_pages_list
249awesome_bar
250awesome_screen
251awesomebar_button
252awesomebar_tabs
253awesomebar_text
254background
255bookmark
256bookmark_icon
257bookmark_title
258bookmark_url
259bookmarks_list
260browser_toolbar
261close
262container
263doorhanger_choices
264doorhanger_container
265doorhanger_title
266favicon
267forward
268gecko_layout
269grid
270history_list
271info
272list
273main_layout
274notification_image
275notification_progressbar
276notification_text
277notification_title
278outline
279plugin_container
280preferences
281quit
282recommended_addon_list
283reload
284save_as_pdf
285screenshot
286select_list
287share
288site_security
289stop
290tabs
291tabs_count
292title
293url
294</pre>
295    <h2>
296      <span class="mw-headline" id="Basic_code_sequences_to_do_di
>fferent_actions">Basic code sequences to do different actions</sp 
>an> 
297    </h2>
298    <ul>
299      <li>Most of the code is already covered by existing methods
> but this code bits will help you understand how Robop works. Bes 
>ides looking over these you should also check out the existing te 
>sts 
300      </li>
301    </ul>
302    <h4>
303      Load Page
304    </h4>
305    <ul>
306      <li>Note that the tests need to use <b>local pages</b> in o
>rder to run on the mozilla setup. Outside pages are not accessibl 
>e 
307      </li>
308      <li>Using an URL
309      </li>
310    </ul>
311    <pre>
312String url = "&lt;insert_link_here&gt;";
313loadUrl(url);
314</pre>
315    <ul>
316      <li>Using the robocop tests blank page
317      </li>
318    </ul>
319    <pre>
320String url = getAbsoluteUrl("/robocop/robocop_blank_01.html");
321loadUrl(url);
322</pre>
323    <h4>
324      Check Page Title
325    </h4>
326    <ul>
327      <li>There has been a method implemented for this in BaseTes
>t.java.in called verifyPageTitle(String title) but the core code  
>to verify the title is: 
328      </li>
329    </ul>
330    <pre>
331Element awesomebar = mDriver.findElement(getActivity(), "awesome_
>bar_title"); // search the awesomebar title 
332mAsserter.isnot(awesomebar, null, "Got the awesomebar"); // log "
>Got the awesomebar" in the logs 
333assertMatches(awesomebar.getText(), "&lt;insert_title_here", "pag
>e title match"); // do a match between expected and actual title 
334</pre>
335    <h4>
336      Open app menu
337    </h4>
338    <ul>
339      <li>There has been a method implemented for this in BaseTes
>t.java.in called selectMenuItem(String item) but the core code fo 
>r opening the menu is: 
340      </li>
341    </ul>
342    <pre>
343mActions.sendSpecialKey(Actions.SpecialKey.MENU);
344//Open the More menu for devices with old style menues
345if (mSolo.waitForText("^More$")) { 
346mSolo.clickOnText("^More$");
347}
348</pre>
349    <h4>
350      Simulate a Back key press:
351    </h4>
352    <pre>
353mActions.sendSpecialKey(Actions.SpecialKey.BACK);
354</pre>
355    <h4>
356      Setup a listener to catch a new page load in a new tab
357    </h4>
358    <ul>
359      <li>This is included in the addTab(String url) method from 
>BaseTest.java.in 
360      </li>
361    </ul>
362    <pre>
363Actions.EventExpecter tabEventExpecter = mActions.expectGeckoEven
>t("Tab:Added"); // Look for a new tab event 
364Actions.EventExpecter contentEventExpecter = mActions.expectGecko
>Event("DOMContentLoaded"); // Look for page load complete 
365</pre>
366    <h4>
367      Wait for the tab and page load
368    </h4>
369    <pre>
370tabEventExpecter.blockForEvent();
371contentEventExpecter.blockForEvent();
372</pre>
373    <h4>
374      Wait for Geko to complete loading
375    </h4>
376    <ul>
377      <li>Include this code at the start of each test to wait for
> Firefox to load completely before starting to do any other actio 
>ns 
378      </li>
379    </ul>
380    <pre>
381blockForGeckoReady();
382</pre>
383    <h4>
384      Open the Bookmarks Tab
385    </h4>
386    <pre>
387private ListView openBookmarksList() {
388    Activity awesomeBarActivity = clickOnAwesomeBar();
389    // Click the "Bookmarks" tab to switch to bookmarks list
390    mSolo.clickOnText("Bookmarks");
391 
392    TabHost tabHost = (TabHost)mSolo.getView(TabHost.class, 0);
393    return (ListView)tabHost.getCurrentView();
394   }
395</pre>
396    <h4>
397      Open the bookmark context menu
398    </h4>
399    <pre>
400View child = list.getChildAt(&lt;nr&gt;); //bookmark nr- <b>numbe
>ring starts at 0 </b> 
401mSolo.clickLongOnView(child); //long tap to open context menu
402</pre>
403    <ul>
404      <li>Similarly you can open the context menu for History and
> Top Sites items 
405      </li>
406    </ul>
407    <h4>
408      Open a new tab and check the tab count
409    </h4>
410    <pre>
411expectedTabCount = &lt;nr_of_expected_tabs&gt;;
412tabCountText = tabCount.getText();
413tabCountInt = Integer.parseInt(tabCountText);
414mAsserter.is(tabCountInt, expectedTabCount, "Number of tabs incre
>ased"); 
415</pre>
416    <h2>
417      Loging info in the Android Logs
418    </h2>
419    <ul>
420      <li>The Assert class can be found in the source folder in t
>he subfolder /obj-android/build/mobile/robocop 
421      </li>
422      <li>Please see the java code for the Assert methods for mor
>e info about how they work 
423      </li>
424      <li>Each Assert will actually determin if a test fails or p
>asses 
425      </li>
426    </ul>
427    <h4>
428      Test that an object is not the same as a second object
429    </h4>
430    <ul>
431      <li>Method signature:
432      </li>
433    </ul>
434    <pre>
435public void isnot(Object a, Object b, String name)
436</pre>
437    <ul>
438      <li>Example for checking that there is a title set for the 
>current page: 
439      </li>
440    </ul>
441    <pre>
442Element awesomebar = mDriver.findElement(getActivity(), "awesome_
>bar_title"); 
443mAsserter.isnot(awesomebar, null, "Got the awesomebar"); // Check
>s that the awesomebar title 
444 is not null and posts in the logs
445</pre>
446    <h4>
447      Test that an object is the same as a second object
448    </h4>
449    <ul>
450      <li>Method signature:
451      </li>
452    </ul>
453    <pre>
454public void is(Object a, Object b, String name)
455</pre>
456    <ul>
457      <li>Example for checking the default bookmarks:
458      </li>
459    </ul>
460    <pre>
461ListView list = getAllPagesList(url);
462mSolo.waitForText(url);
463 
464mAsserter.is(list.getChildCount(), 5, "all pages list has 5 child
>ren (the default bookmarks)"); // Checks that  
465there are 5 entries in the list and posts in the logs
466</pre>
467    <h4>
468      Write text in the Logs
469    </h4>
470    <ul>
471      <li>Method signature:
472      </li>
473    </ul>
474    <pre>
475public void dumpLog(String message) // writes text in the logs
476</pre>
477    <h4>
478      Log info about test progression
479    </h4>
480    <ul>
481      <li>Method signature:
482      </li>
483    </ul>
484    <pre>
485public void ok(boolean condition, String name, String diag) 
486</pre>
487    <ul>
488      <li>Example
489      </li>
490    </ul>
491    <pre>
492ListView list = getAllPagesList(url);
493mSolo.waitForText(url);
494 
495mAsserter.ok(list != null, "checking that all pages list exists",
> list.toString()); // tests if  
496the list is null and if it isn't it prints the list after printin
>g the message of what the test does 
497</pre>
498    <h2>
499      Updating your test directory
500    </h2>
501    <p>
502      t is not always necessary to rebuild Fennec to use new test
>s. If you are updating the build with your own test, ensure that  
>your test has been added to the manifest in /PATH/TO/FENNEC/SOURC 
>E/mobile/android/base/tests/robocop.ini . 
503    </p>
504    <p>
505      Otherwise, you can retrieve tests from the repository by ex
>ecuting: 
506    </p>
507    <pre>
508hg pull
509hg update
510</pre>
511    <p>
512      Now you can build the robocop part of Fennec by executing:
513    </p>
514    <pre>
515cd objdir
516sudo make -C build/mobile/robocop/
517sudo make package 
518</pre>
519    <h2>
520      Testing and submitting the test as a patch
521    </h2>
522    <ul>
523      <li>Make sure your code follows the basic coding style guid
>elines. <a href="https://developer.mozilla.org/en-US/docs/Basic_C 
>ode_Styling_Guidelines_for_Robocop_tests" title="https://develope 
>r.mozilla.org/en-US/docs/Basic_Code_Styling_Guidelines_for_Roboco 
>p_tests">In this article</a> there are a few guidelines that shou 
>ld be followed. 
524      </li>
525      <li>Make sure you run the test at least 5 times to make sur
>e there are no intermitent fails caused by timings 
526      </li>
527      <li>If you have access to the tryserver(Commit access level
> 1) run the patch on the tryserver and it passes the tests 
528      </li>
529      <li>Once you are sure the test works you can create a patch
> and add it to a bug. If there isn't a bug already to cover the c 
>reation of the test create one 
530      </li>
531      <li>If you need help creating a patch please read the docum
>entation covering the this from <a href="https://wiki.mozilla.org 
>/QA_SoftVision_Team/Mobile/Writing_tests#Creating_a_diff_patch_fi 
>le" title="https://wiki.mozilla.org/QA_SoftVision_Team/Mobile/Wri 
>ting_tests#Creating_a_diff_patch_file">this wiki page</a> 
532      </li>
533    </ul>

Back to History