Merge lp:~javier.collado/mago/firefox into lp:~mago-contributors/mago/mago-1.0

Proposed by Javier Collado
Status: Rejected
Rejected by: Javier Collado
Proposed branch: lp:~javier.collado/mago/firefox
Merge into: lp:~mago-contributors/mago/mago-1.0
Diff against target: 480 lines
8 files modified
firefox/firefox_init_test.py (+20/-0)
firefox/firefox_init_test.xml (+13/-0)
firefox/firefox_test.py (+155/-0)
firefox/firefox_test.xml (+43/-0)
mago/application/__init__.py (+1/-1)
mago/application/mozilla.py (+179/-0)
mago/test_suite/__init__.py (+1/-1)
mago/test_suite/mozilla.py (+20/-0)
To merge this branch: bzr merge lp:~javier.collado/mago/firefox
Reviewer Review Type Date Requested Status
Ara Pulido Needs Information
Nagappan Alagappan Approve
Review via email: mp+13060@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Javier Collado (javier.collado) wrote :

This branch implements a few firefox test cases. More test cases are expected to be added (and merged) in the future.

Instead of creating firefox.py modules for application and test suite, the name used is mozilla.py just in case some other mozilla application test case is automated in the future.

Revision history for this message
Nagappan Alagappan (nagappan) :
review: Approve
Revision history for this message
Ara Pulido (ara) wrote :

Hello Javier and Nagappan,

There are some comments I would like to make regarding these changes.

1) I see too many literals all around the code. Shouldn't those be moved as class constants?
2) The way to put URL is too fragile.

In firefox 3.5 is possible to set text in the URL bar as:

import ooldtp
import ldtp

firefox = ooldtp.context("frmUbuntuStartPage-MozillaFirefox")

txt = firefox.getchild("txtSearchBookmarksandHistory")
txt.settextvalue("www.launchpad.net")

ldtp.waittillguiexist("frmUbuntuStartPage-MozillaFirefox", 'btnGo*')
ldtp.click("frmUbuntuStartPage-MozillaFirefox", 'btnGo*')
ldtp.waittillguiexist("frmUbuntuStartPage-MozillaFirefox", 'btnDone')

The problem is still that the btnGo is not shown until the application gets the focus.

Nagappan, I tried using ldtputils.activatewindow as:

ldtputils.activatewindow("frmUbuntuStartPage-MozillaFirefox")

but it didn't work

any ideas?

review: Needs Fixing
Revision history for this message
Javier Collado (javier.collado) wrote :

Hello,

1) Each literal is used once/twice and in just one method. It's a matter of taste, but I think that in this case constants don't improve readability and/or maintainability. However, if that's the style that is agreed for the code in the project, I could change it.

2) I agree. Indeed, for the test cases to work fine Firefox window must be focused and mouse mustn't point to anything that prevents the status bar from displaying 'Done' when a page has been loaded.

As you probably have seen in the code comments, I already tried settextvalue, but it didn't work so I'd happy to implement any other solution that is proposed in this thread.

Best regards,
    Javier

Revision history for this message
Nagappan Alagappan (nagappan) wrote :

> Nagappan, I tried using ldtputils.activatewindow as:
>
> ldtputils.activatewindow("frmUbuntuStartPage-MozillaFirefox")
>
> but it didn't work
>
> any ideas?

Ara, In VMware Workstation automation, we grab the window using a button on the window and then do the required event.

Let us take gedit as an example here:

grabfocus('*-gedit', 'btnFind')

# Now do the required action. The above grabfocus will bring the window to focus.

Hope this helps.

Thanks

Revision history for this message
Ara Pulido (ara) wrote :

>
> # Now do the required action. The above grabfocus will bring the window to
> focus.

I am afraid it does not work for Firefox. Doing any action on firefox does not bring it to focus. Nor it does clicking on buttons and the alike (the button gets clicked, but the window is not brought to focus)

Any other ideas?

review: Needs Information
Revision history for this message
Eitan Isaacson (eeejay) wrote :

> >
> > # Now do the required action. The above grabfocus will bring the window to
> > focus.
>
> I am afraid it does not work for Firefox. Doing any action on firefox does not
> bring it to focus. Nor it does clicking on buttons and the alike (the button
> gets clicked, but the window is not brought to focus)
>
> Any other ideas?

Sorry if I don't know what I am talking about...
What about using wnck to explicitly activate the window? This should be exposed in LDTP of course, to keep the server/client separation.

Revision history for this message
Eitan Isaacson (eeejay) wrote :

> > >
> > > # Now do the required action. The above grabfocus will bring the window to
> > > focus.
> >
> > I am afraid it does not work for Firefox. Doing any action on firefox does
> not
> > bring it to focus. Nor it does clicking on buttons and the alike (the button
> > gets clicked, but the window is not brought to focus)
> >
> > Any other ideas?
>
> Sorry if I don't know what I am talking about...
> What about using wnck to explicitly activate the window? This should be
> exposed in LDTP of course, to keep the server/client separation.

Also, it won't work in the script. It needs an event loop, the LDTPv2 daemon has one, and simple wnck ops should just work from it, no need for any fancy event loop hacking.

Revision history for this message
Nagappan Alagappan (nagappan) wrote :

> > > >
> > > > # Now do the required action. The above grabfocus will bring the window
> to
> > > > focus.
> > >
> > > I am afraid it does not work for Firefox. Doing any action on firefox does
> > not
> > > bring it to focus. Nor it does clicking on buttons and the alike (the
> button
> > > gets clicked, but the window is not brought to focus)
> > >
> > > Any other ideas?
> >
> > Sorry if I don't know what I am talking about...
> > What about using wnck to explicitly activate the window? This should be
> > exposed in LDTP of course, to keep the server/client separation.
>
> Also, it won't work in the script. It needs an event loop, the LDTPv2 daemon
> has one, and simple wnck ops should just work from it, no need for any fancy
> event loop hacking.

Have implemented wnck functions in LDTPv2. Request to verify the same. It also exist in LDTPv1 1.7.1 release as well.

Sorry for the delay

Thanks

Revision history for this message
Ara Pulido (ara) wrote :

So, we have here two issues with WNCK wrappers in LDTP.

The first one (and most important), is that WNCK activate window is not working. I filed that as bug 603115 in bugzilla (https://bugzilla.gnome.org/show_bug.cgi?id=603115) and attach a patch that fixes it.

The second one (and less important), is that WNCK wrappers only work with the WNCK window name (and not LDTP names).

So, with the first patch applied, the following code works perfectly:

import ooldtp
import ldtp
import ldtputils

firefox = ooldtp.context("frmUbuntuStartPage-MozillaFirefox")

ldtputils.activatewindow('Ubuntu Start Page - Mozilla Firefox')
mnu = firefox.getchild("mnuOpenLocation*")
mnu.click()
txt = firefox.getchild("txtSearchBookmarksandHistory")
txt.settextvalue("www.launchpad.net")

ldtp.waittillguiexist("frmUbuntuStartPage-MozillaFirefox", 'btnGo*')
ldtp.click("frmUbuntuStartPage-MozillaFirefox", 'btnGo*')

So, my suggestion is:

If the patch gets accepted, apply the patch to the LDTP package in Lucid
Branch mago for karmic
Change the test to use the wnck function to be more reliable
Accept the new merge into trunk (now targeting Lucid)

What do you guys think?

Revision history for this message
Ara Pulido (ara) wrote :

>
> The second one (and less important), is that WNCK wrappers only work with the
> WNCK window name (and not LDTP names).
>

I forgot to say that this one was file as bug 603118 in bugzilla (https://bugzilla.gnome.org/show_bug.cgi?id=603118)

Revision history for this message
Javier Collado (javier.collado) wrote :

Closing merge proposal since it's quite old.

Unmerged revisions

119. By Javier Collado

Typo fixed

118. By Javier Collado

Removing metadata that was used in unr branch

117. By Javier Collado

Minor changes to make the tests work in jaunty also

116. By Javier Collado

Some more changes to make tests work in karmic

115. By Javier Collado

Firefox test cases from unr branch added and updated

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'firefox'
2=== added file 'firefox/firefox_init_test.py'
3--- firefox/firefox_init_test.py 1970-01-01 00:00:00 +0000
4+++ firefox/firefox_init_test.py 2009-10-08 11:20:26 +0000
5@@ -0,0 +1,20 @@
6+#!/usr/bin/python
7+import ldtp
8+from mago.test_suite.mozilla import FirefoxTestSuite as BaseTestSuite
9+
10+class FirefoxInitTestSuite(BaseTestSuite):
11+ """
12+ Test cases to verify firefox initial functionality
13+ """
14+ def test_open_and_close(self):
15+ """
16+ Open and close firefox
17+
18+ Detailed procedure:
19+ * Launch application
20+ * Check that main window exist
21+ * Close main window
22+ * Check that main window doesn't exist
23+ """
24+ self.application.open()
25+ self.application.close()
26
27=== added file 'firefox/firefox_init_test.xml'
28--- firefox/firefox_init_test.xml 1970-01-01 00:00:00 +0000
29+++ firefox/firefox_init_test.xml 2009-10-08 11:20:26 +0000
30@@ -0,0 +1,13 @@
31+<?xml version="1.0"?>
32+<suite name="Firefox Initial Test Suite">
33+ <class>firefox_init_test.FirefoxInitTestSuite</class>
34+ <description>
35+ Test cases to verify Firefox initial functionality
36+ </description>
37+ <case name="Open and close">
38+ <method>test_open_and_close</method>
39+ <description>
40+ Open and close Firefox
41+ </description>
42+ </case>
43+</suite>
44
45=== added file 'firefox/firefox_test.py'
46--- firefox/firefox_test.py 1970-01-01 00:00:00 +0000
47+++ firefox/firefox_test.py 2009-10-08 11:20:26 +0000
48@@ -0,0 +1,155 @@
49+#!/usr/bin/python
50+import ldtp
51+from mago.test_suite.mozilla import FirefoxTestSuite as BaseTestSuite
52+try:
53+ import lsb_release
54+except ImportError:
55+ import subprocess
56+ lsb_release = None
57+
58+class FirefoxTestSuite(BaseTestSuite):
59+ """
60+ Test cases to verify basic firefox functionality
61+ """
62+ # Get Ubuntu release number either from python package or command line
63+ if lsb_release:
64+ release = lsb_release.get_distro_information()['RELEASE']
65+ else:
66+ release = subprocess.Popen(["lsb_release", "-r"],
67+ stdout=subprocess.PIPE).communicate()[0].split()[1]
68+
69+ DEFAULT_HOME_PAGE = {'chrome': 'chrome://ubufox/content/startpage.html',
70+ 'http': 'http://start.ubuntu.com/%s/' % release}
71+ URL = {'canonical': "http://www.canonical.com/",
72+ 'ubuntu': "http://www.ubuntu.com/",
73+ }
74+ TAB = {'canonical': "scpn*Canonical",
75+ 'ubuntu': "scpn*Ubuntu",
76+ 'new': "scpn(Untitled)",
77+ }
78+
79+
80+ def setup(self):
81+ """
82+ Open Firefox by default when suite starts
83+ """
84+ BaseTestSuite.setup(self)
85+ self.application.open()
86+
87+
88+ def cleanup(self):
89+ BaseTestSuite.cleanup(self)
90+ self.application.close()
91+ # Firefox cannot be restarted immediatly
92+ ldtp.wait()
93+ self.application.open()
94+
95+
96+ def teardown(self):
97+ """
98+ Open firefox when test suite finishes
99+ """
100+ self.application.close()
101+
102+
103+ def test_new_location(self):
104+ """
105+ Enter a new location and load it
106+
107+ Detailed procedure:
108+ * Enter new URL in the location text box
109+ * Wait until status bar says "Done"
110+ """
111+ self.application.load_page(self.URL["canonical"])
112+
113+
114+ def test_home_page(self):
115+ """
116+ Update home page configuration
117+
118+ Detailed procedure:
119+ * Load a page different than home
120+ * Open preferences dialog
121+ * Get home page value
122+ * Press home button
123+ * Verify that location text box has been correctly updated
124+ """
125+ self.application.load_page(self.URL["canonical"])
126+ self.application.open_preferences()
127+ home_page = ldtp.gettextvalue(self.application.PREFERENCES_WINDOW, 'txtHomePage')
128+ assert home_page == self.DEFAULT_HOME_PAGE['chrome']
129+ self.application.close_preferences()
130+ self.application.go_home()
131+ assert self.application.location == self.DEFAULT_HOME_PAGE['http']
132+
133+
134+ def test_new_tab(self):
135+ """
136+ Open new tab
137+
138+ Detailed procedure:
139+ * Check that there is just one tab opened
140+ * Select new tab menu item
141+ * Check that there are now two tabs opened
142+ * Close the new tab
143+ * Check that there is again just one tab opened
144+ """
145+ assert 1 == len(self.application.tabs)
146+ self.application.open_tab()
147+ self.application.load_page(self.URL['canonical'])
148+ ldtp.waittillguiexist(self.application.WINDOW, self.TAB['canonical'])
149+ assert 2 == len(self.application.tabs)
150+ self.application.close_tab()
151+ ldtp.waittillguinotexist(self.application.WINDOW, self.TAB['canonical'])
152+ assert 1 == len(self.application.tabs)
153+
154+
155+ def test_new_window(self):
156+ """
157+ Open new window
158+
159+ Detailed procedure:
160+ * Check that there is just one window opened
161+ * Select new window menu item
162+ * Check that there are now two windows opened
163+ * Close the new window
164+ * Check that there is again just one window opened
165+ """
166+ assert 1 == len(self.application.windows)
167+ self.application.load_page(self.URL['canonical'])
168+ window = self.application.open_window()
169+ assert 2 == len(self.application.windows)
170+ self.application.close_window(window)
171+ assert 1 == len(self.application.windows)
172+
173+
174+ def test_back_forward(self):
175+ """
176+ Back and forward buttons
177+
178+ Detailed procedure:
179+ * Load page 1
180+ * Load page 2
181+ * Press back button
182+ * (Page 1 is loaded)
183+ * Press forward button
184+ * (Page 2 is loaded)
185+ """
186+ self.application.load_page(self.URL['canonical'])
187+ self.application.load_page(self.URL['ubuntu'])
188+ self.application.go_back()
189+ assert self.application.location == self.URL['canonical']
190+ self.application.go_forward()
191+ assert self.application.location == self.URL['ubuntu']
192+
193+
194+ def test_search(self):
195+ """
196+ Search a string
197+
198+ Detailed procedure:
199+ * Type query string
200+ * Wait until status bar says "Done"
201+ """
202+ ldtp.generatekeyevent('<ctrl>kubuntu<enter>')
203+ ldtp.waittillguiexist(self.application.WINDOW, 'btnDone')
204
205=== added file 'firefox/firefox_test.xml'
206--- firefox/firefox_test.xml 1970-01-01 00:00:00 +0000
207+++ firefox/firefox_test.xml 2009-10-08 11:20:26 +0000
208@@ -0,0 +1,43 @@
209+<?xml version="1.0"?>
210+<suite name="Firefox Test Suite">
211+ <class>firefox_test.FirefoxTestSuite</class>
212+ <description>
213+ Test cases to verify basic Firefox functionality
214+ </description>
215+ <case name="Back and forward">
216+ <method>test_back_forward</method>
217+ <description>
218+ Back and forward buttons
219+ </description>
220+ </case>
221+ <case name="Home page">
222+ <method>test_home_page</method>
223+ <description>
224+ Update home page configuration
225+ </description>
226+ </case>
227+ <case name="Enter new location">
228+ <method>test_new_location</method>
229+ <description>
230+ Enter a new location and load it
231+ </description>
232+ </case>
233+ <case name="New tab">
234+ <method>test_new_tab</method>
235+ <description>
236+ Open new tab
237+ </description>
238+ </case>
239+ <case name="New window">
240+ <method>test_new_window</method>
241+ <description>
242+ Open new window
243+ </description>
244+ </case>
245+ <case name="Search">
246+ <method>test_search</method>
247+ <description>
248+ Search a string
249+ </description>
250+ </case>
251+</suite>
252
253=== modified file 'mago/application/__init__.py'
254--- mago/application/__init__.py 2009-06-15 10:58:35 +0000
255+++ mago/application/__init__.py 2009-10-08 11:20:26 +0000
256@@ -3,4 +3,4 @@
257
258 Classes that wrap application functionality to ease their testing
259 """
260-__all__ = ['main', 'gnome', 'ubuntu', 'pidgin', 'evolution']
261+__all__ = ['main', 'gnome', 'ubuntu', 'pidgin', 'evolution', 'mozilla']
262
263=== added file 'mago/application/mozilla.py'
264--- mago/application/mozilla.py 1970-01-01 00:00:00 +0000
265+++ mago/application/mozilla.py 2009-10-08 11:20:26 +0000
266@@ -0,0 +1,179 @@
267+"""
268+LDTP wrappers for mozilla applications
269+"""
270+import os, fnmatch
271+
272+import ldtp
273+from .main import Application
274+
275+class Firefox(Application):
276+ """
277+ Firefox web browser
278+ """
279+ WINDOW = "frm*MozillaFirefox*"
280+ START_WINDOW = "frmUbuntuStartPage-MozillaFirefox"
281+ PREFERENCES_WINDOW = "*FirefoxPreferences"
282+ LAUNCHER = "firefox"
283+ QUIT_DIALOG = 'dlgQuitFirefox'
284+
285+ def close(self):
286+ """
287+ Close Firefox safely (take into account close dialog)
288+ """
289+ self.close_window()
290+# while self.LAUNCHER in ldtp.getapplist():
291+# ldtp.wait()
292+
293+
294+ def open_preferences(self):
295+ """
296+ Open preferences window
297+ """
298+ ldtp.click(self.WINDOW, 'mnuPreferences')
299+ ldtp.waittillguiexist(self.PREFERENCES_WINDOW)
300+
301+
302+ def close_preferences(self):
303+ """
304+ Close preferences window
305+ """
306+ ldtp.click(self.PREFERENCES_WINDOW, 'btnClose')
307+ ldtp.waittillguinotexist(self.PREFERENCES_WINDOW)
308+
309+
310+ def load_page(self, url):
311+ """
312+ Load a new web page for the given URL
313+ """
314+ # The code below isn't currently working because of a failure
315+ # in Firefox. Please take a look at bug 462367
316+ # in bugzilla.mozilla.org for more information
317+ #ldtp.settextvalue(self.WINDOW, 'txtLocation', self.URL)
318+ #assert 1 == ldtp.verifysettext(self.WINDOW, 'txtLocation', self.URL)
319+ #ldtp.activatetext(self.WINDOW, 'txtLocation')
320+
321+ # This code is the alternate version of the previous one, but
322+ # is based on the expectation that Firefox will be the
323+ # application with the focus (which is something difficult to
324+ # know for sure)
325+ # Note: Prefix is removed from URL because it seems isn't
326+ # being correctly sent by LDTP (maybe it's an escap problem)
327+ short_url = url.replace('http://', '').replace('/','')
328+ ldtp.generatekeyevent('<ctrl>l%s' % short_url)
329+ ldtp.waittillguiexist(self.WINDOW, 'btnGo*')
330+ ldtp.click(self.WINDOW, 'btnGo*')
331+ ldtp.waittillguiexist(self.WINDOW, 'btnDone')
332+ assert self.location == url, "%s != %s" % (self.location, url)
333+
334+
335+ def open_tab(self):
336+ """
337+ Open a new tab by selecting the new tab menu
338+ """
339+ ldtp.click(self.WINDOW, 'mnuNewTab')
340+ ldtp.waittillguiexist(self.WINDOW, 'scpn(Untitled)')
341+
342+
343+ def close_tab(self):
344+ """
345+ Close a tab by selecting the close tab menu
346+ """
347+ ldtp.click(self.WINDOW, 'mnuCloseTab')
348+
349+
350+ def open_window(self):
351+ """
352+ Open a new window by selecting new window menu
353+ """
354+ ldtp.click(self.WINDOW, 'mnuNewWindow')
355+ ldtp.waittillguiexist(self.START_WINDOW)
356+ return self.START_WINDOW
357+
358+
359+ def close_window(self, window = None):
360+ """
361+ Close a window by selecting close menu
362+ """
363+ if len(self.windows) == 1:
364+ close_menu = 'mnuQuit'
365+ else:
366+ objects = ldtp.getobjectlist(self.WINDOW)
367+
368+ if 'mnuCloseWindow' in objects: # Firefox 3.5
369+ close_menu = 'mnuCloseWindow'
370+ elif 'mnuClose' in objects: # Firefox 3.0
371+ close_menu = 'mnuClose'
372+ else:
373+ raise ldtp.LdtpExecutionError('Close menu object not found')
374+
375+ if window is None:
376+ window = self.WINDOW
377+ ldtp.click(window, close_menu)
378+ success = ldtp.waittillguinotexist(window, guiTimeOut=5)
379+ if not success and self.QUIT_DIALOG in ldtp.getwindowlist():
380+ ldtp.click(self.QUIT_DIALOG, 'btnQuit')
381+ ldtp.waittillguinotexist(self.QUIT_DIALOG)
382+ ldtp.waittillguinotexist(window)
383+
384+
385+ def go_home(self):
386+ """
387+ Load home page
388+ """
389+ self._go('btnHome')
390+
391+
392+ def go_back(self):
393+ """
394+ Go one step back in browsing history
395+ """
396+ self._go('btnBack')
397+
398+
399+ def go_forward(self):
400+ """
401+ Go one step back in browsing history
402+ """
403+ self._go('btnForward')
404+
405+
406+ def _go(self, button):
407+ """
408+ Press one button and wait for page to be loaded
409+ """
410+ ldtp.click(self.WINDOW, button)
411+ ldtp.waittillguiexist(self.WINDOW, 'btnDone')
412+
413+
414+ @property
415+ def location(self):
416+ """
417+ Return current location
418+ """
419+ objects = ldtp.getobjectlist(self.WINDOW)
420+
421+ if 'txtSearchBookmarksandHistory' in objects: # Firefox 3.5
422+ location = ldtp.gettextvalue(self.WINDOW, 'txtSearchBookmarksandHistory')
423+ elif 'txtLocation' in objects: # Firefox 3.0
424+ location = ldtp.gettextvalue(self.WINDOW, 'txtLocation')
425+ else:
426+ raise ldtp.LdtpExecutionError('Location object not found')
427+
428+ return location
429+
430+
431+ @property
432+ def tabs(self):
433+ """
434+ Get a list of tab controls
435+ """
436+ return [object for object in ldtp.getobjectlist(self.WINDOW)
437+ if object.startswith('scpn')]
438+
439+ @property
440+ def windows(self):
441+ """
442+ Get a list of application windows
443+ """
444+ return [window for window in ldtp.getwindowlist()
445+ if fnmatch.fnmatch(window, self.WINDOW)]
446
447=== modified file 'mago/test_suite/__init__.py'
448--- mago/test_suite/__init__.py 2009-06-15 10:58:35 +0000
449+++ mago/test_suite/__init__.py 2009-10-08 11:20:26 +0000
450@@ -3,4 +3,4 @@
451
452 Test suite classes that implement setup/teardown/cleanup methods
453 """
454-__all__ = ['main', 'gnome', 'ubuntu', 'pidgin', 'evolution']
455+__all__ = ['main', 'gnome', 'ubuntu', 'pidgin', 'evolution', 'mozilla']
456
457=== added file 'mago/test_suite/mozilla.py'
458--- mago/test_suite/mozilla.py 1970-01-01 00:00:00 +0000
459+++ mago/test_suite/mozilla.py 2009-10-08 11:20:26 +0000
460@@ -0,0 +1,20 @@
461+"""
462+ubuntu module contains the definition of the test suites used for ubuntu
463+applications
464+"""
465+import ldtp
466+from .main import SingleApplicationTestSuite
467+from ..application.mozilla import Firefox
468+
469+class FirefoxTestSuite(SingleApplicationTestSuite):
470+ """
471+ Base clase for firefox test suites
472+ """
473+ APPLICATION_FACTORY = Firefox
474+
475+ def setup(self):
476+ """
477+ Check that no Firefox instance is running
478+ """
479+ assert 'Firefox' not in ldtp.getapplist(), \
480+ "At least one Firefox instance is already running"

Subscribers

People subscribed via source and target branches

to status/vote changes: