Summary ------- Moved the remaining registry windmill tests from lib/canonical/launchpad/windmill/tests to lib/lp/registry/windmill/tests. Implementation details ---------------------- Most of the changes just involve boilerplate to convert the tests to unittests, indenting functions that became methods, and replacing client with self.client. I've included a smaller diff below of the changes that were made to fix regressions since these tests had not been automatically run. I also encountered authentication problems with the lpuser module's ensure_login() method. Some of the tests use helper functions from a different module that creates a new windmill client each time the function is called. I assume there is something in the initialization of the new client that invalidates the cookie from the last client, therefore, I have to load a page in the new client before calling ensure_login() so that it can find the "Login" link, otherwise it assumes it is still logged in just fine. lib/lp/registry/browser/product.py The windmill test was using foo.bar instead of the owner of the project, so it seemed better to fix this by allowing anyone with launchpad.Edit access to be able to see the programming language fields inline editing icon. lib/lp/registry/templates/milestone-index.pt lib/lp/registry/windmill/tests/test_add_milestone.py Creating a release now takes you to the milestone/release index page instead of the series index page. The ids were added to simplify the tests. lib/lp/registry/templates/product-new.pt node.attach() was replaced with node.on(), so this functionality was actually broken in production. lib/lp/registry/windmill/tests/test_plusnew_step1.py lib/lp/registry/windmill/tests/test_plusnew_step2.py lib/lp/registry/windmill/tests/test_product.py lib/lp/registry/windmill/tests/test_project_licenses.py Tests ----- ./bin/test -vv --layer=RegistryWindmillLayer {{{ === modified file 'lib/canonical/launchpad/windmill/testing/widgets.py' --- lib/canonical/launchpad/windmill/testing/widgets.py 2009-10-29 14:23:16 +0000 +++ lib/canonical/launchpad/windmill/testing/widgets.py 2009-12-11 00:22:50 +0000 @@ -60,10 +60,10 @@ * reloads and verifies that the new value sticked. """ client = WindmillTestClient(self.suite) + client.open(url=self.url) self.user.ensure_login(client) - client.open(url=self.url) client.waits.forPageLoad(timeout=constants.PAGE_LOAD) widget_base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id) client.waits.forElement( @@ -298,13 +298,15 @@ def __call__(self): client = WindmillTestClient(self.suite) - self.user.ensure_login(client) # Load page. client.open(url=self.url) - client.waits.forPageLoad(timeout=constants.PAGE_LOAD) + + self.user.ensure_login(client) # Click on "Choose" link to show picker for the given field. + client.waits.forElement( + id=self.choose_link_id, timeout=constants.PAGE_LOAD) client.click(id=self.choose_link_id) # Search picker. === modified file 'lib/lp/registry/browser/product.py' --- lib/lp/registry/browser/product.py 2009-12-05 18:37:28 +0000 +++ lib/lp/registry/browser/product.py 2009-12-10 22:21:00 +0000 @@ -778,7 +778,7 @@ **additional_arguments) self.show_programming_languages = bool( self.context.programminglang or - self.user == self.context.owner) + check_permission('launchpad.Edit', self.context)) @property def show_license_status(self): === modified file 'lib/lp/registry/templates/milestone-index.pt' --- lib/lp/registry/templates/milestone-index.pt 2009-11-15 19:37:56 +0000 +++ lib/lp/registry/templates/milestone-index.pt 2009-12-11 16:59:49 +0000 @@ -53,12 +53,12 @@ tal:condition="view/milestone/series_target" /> -
+
Version:
-
+
Code name:
=== modified file 'lib/lp/registry/templates/product-new.pt' --- lib/lp/registry/templates/product-new.pt 2009-12-03 18:33:22 +0000 +++ lib/lp/registry/templates/product-new.pt 2009-12-10 21:30:22 +0000 @@ -100,7 +100,7 @@ url_field.on('keyup', function(e) { if (url_field.get('value') == '') { /* The user cleared the URL field; turn on autofill. */ - name_field.attach('keyup', autofill); + name_field.on('keyup', autofill); } else { /* Honor the user's URL; turn off autofill. */ === modified file 'lib/lp/registry/windmill/tests/test_add_milestone.py' --- lib/lp/registry/windmill/tests/test_add_milestone.py 2009-12-10 17:52:56 +0000 +++ lib/lp/registry/windmill/tests/test_add_milestone.py 2009-12-11 17:01:53 +0000 @@ -61,8 +61,8 @@ client.waits.forElement(id=u'field.name', timeout=u'8000') client.type(id='field.name', text=milestone_name) client.click(id=u'formoverlay-add-milestone') - client.asserts.assertText( - id='milestone-error', + client.asserts.assertTextIn( + classname='yui-lazr-formoverlay-errors', validator='The name %s is already used' % milestone_name.lower()) client.click(classname='close-button') @@ -74,14 +74,11 @@ client.waits.forPageLoad(timeout=u'20000') # Verify that the release was created. - milestone_xpath = ( - "//table[@id='series_trunk']//a[@href='/bzr/+milestone/%s']" - % milestone_name.lower()) - client.waits.forElement(xpath=milestone_xpath, timeout=u'8000') - client.asserts.assertText( - xpath=milestone_xpath, validator=milestone_name.lower()) - client.asserts.assertText( - xpath=milestone_xpath, validator=code_name) + client.waits.forElement(id="version") + client.asserts.assertText( + xpath="//*[@id='version']/dd", validator=milestone_name.lower()) + client.asserts.assertText( + xpath="//*[@id='code-name']/dd", validator=code_name) class TestAddMilestone(TestCaseWithFactory): @@ -94,6 +91,7 @@ def test_adding_milestone_on_addrelease_page(self): test_inline_add_milestone( + self.client, url='http://launchpad.dev:8085/bzr/trunk/+addrelease', name='test_inline_add_milestone_for_release') === modified file 'lib/lp/registry/windmill/tests/test_plusnew_step1.py' --- lib/lp/registry/windmill/tests/test_plusnew_step1.py 2009-12-10 17:52:56 +0000 +++ lib/lp/registry/windmill/tests/test_plusnew_step1.py 2009-12-11 19:53:37 +0000 @@ -15,6 +15,8 @@ from lp.registry.windmill.testing import RegistryWindmillLayer from lp.testing import TestCaseWithFactory +BACKSPACE = u'\x08' + class TestNewProjectStep1(TestCaseWithFactory): """Test form for creating a new project.""" @@ -30,13 +32,13 @@ On step 1 of the wizard, the URL field gets autofilled from the Name field. Also, the URL field will not accept invalid characters. """ - lpuser.SAMPLE_PERSON.ensure_login(self.client) - # Perform step 1 of the project registration, using information # that will yield search results. self.client.open(url=u'http://launchpad.dev:8085/projects/+new') - self.client.waits.forPageLoad(timeout=u'20000') - + + lpuser.SAMPLE_PERSON.ensure_login(self.client) + + self.client.waits.forElement(id='field.displayname') self.client.type(text=u'dolphin', id='field.displayname') # The field is forced to lower case by a CSS text-transform, but @@ -59,7 +61,7 @@ validator=u'mongoose') # But once we clear the URL field, autofilling is re-enabled. Type a # backspace character to trigger this. - self.client.type(text=u'\x08', id='field.name') + self.client.type(text=BACKSPACE, id='field.name') self.client.type(text='hyena', id='field.displayname') self.client.asserts.assertValue( id=u'field.name', === modified file 'lib/lp/registry/windmill/tests/test_plusnew_step2.py' --- lib/lp/registry/windmill/tests/test_plusnew_step2.py 2009-12-10 17:52:56 +0000 +++ lib/lp/registry/windmill/tests/test_plusnew_step2.py 2009-12-11 16:00:50 +0000 @@ -35,13 +35,13 @@ and hiding them. """ - lpuser.SAMPLE_PERSON.ensure_login(self.client) - # Perform step 1 of the project registration, using information # that will yield search results. self.client.open(url=u'http://launchpad.dev:8085/projects/+new') - self.client.waits.forPageLoad(timeout=u'20000') - + + lpuser.SAMPLE_PERSON.ensure_login(self.client) + + self.client.waits.forElement(id='field.displayname', timeout=u'20000') self.client.type(text=u'Badgers', id='field.displayname') self.client.type(text=u'badgers', id='field.name') self.client.type(text=u"There's the Badger", id='field.title') @@ -49,7 +49,7 @@ self.client.click(id=u'field.actions.continue') self.client.waits.forPageLoad(timeout=u'20000') # The h2 heading indicates that a search was performed. - self.client.asserts.assertText( + self.client.asserts.assertTextIn( id=u'step-title', validator=u'Check for duplicate projects') @@ -58,7 +58,7 @@ # for toggling the search results. It also changes the h2 title # to something more appropriate. self.client.click(id=u'registration-details-buttons') - self.client.asserts.assertText( + self.client.asserts.assertTextIn( id=u'step-title', validator=u'Registration details') === modified file 'lib/lp/registry/windmill/tests/test_project_licenses.py' --- lib/lp/registry/windmill/tests/test_project_licenses.py 2009-12-10 17:52:56 +0000 +++ lib/lp/registry/windmill/tests/test_project_licenses.py 2009-12-11 17:36:22 +0000 @@ -26,16 +26,16 @@ def test_project_licenses(self): """Test the dynamic aspects of the project license picker.""" + # The firefox project is as good as any. + self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit') + self.client.waits.forPageLoad(timeout=u'20000') + lpuser.SAMPLE_PERSON.ensure_login(self.client) - # The firefox project is as good as any. - self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit') - self.client.waits.forPageLoad(timeout=u'20000') - # The Recommended table is visible. - self.client.asserts.assertProperty( + self.client.waits.forElementProperty( id=u'recommended', - validator='className|lazr-opened') + option='className|lazr-opened') # But the More table is not. self.client.asserts.assertProperty( id=u'more', @@ -47,23 +47,21 @@ # Clicking on the link exposes the More section though. self.client.click(id='more-expand') - self.client.waits.sleep(milliseconds=u'1000') - self.client.asserts.assertProperty( + self.client.waits.forElementProperty( id=u'more', - validator='className|lazr-opened') + option='className|lazr-opened') # As does clicking on the Other choices section. self.client.click(id='special-expand') - self.client.waits.sleep(milliseconds=u'1000') - self.client.asserts.assertProperty( + self.client.waits.forElementProperty( id=u'special', - validator='className|lazr-opened') + option='className|lazr-opened') # Clicking on any opened link closes the section. self.client.click(id='recommended-expand') - self.client.asserts.assertProperty( + self.client.waits.forElementProperty( id=u'recommended', - validator='className|lazr-closed') + option='className|lazr-closed') # The license details box starts out hidden. self.client.asserts.assertProperty( @@ -98,9 +96,9 @@ validator='className|lazr-opened') self.client.click(id='field.licenses.25') - self.client.asserts.assertProperty( + self.client.waits.forElementProperty( id=u'license-details', - validator='className|lazr-closed') + option='className|lazr-closed') self.client.asserts.assertProperty( id=u'proprietary', validator='className|lazr-closed') @@ -109,9 +107,9 @@ # closes the details box, but leaves the sections opened. self.client.click(id='field.licenses.25') - self.client.asserts.assertProperty( + self.client.waits.forElementProperty( id=u'license-details', - validator='className|lazr-opened') + option='className|lazr-opened') self.client.asserts.assertChecked( id=u'field.licenses.25') }}}