← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:zope.testbrowser-5-prepare into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:zope.testbrowser-5-prepare into launchpad:master.

Commit message:
Improve compatibility with zope.testbrowser 5.x

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/375407

Upgrading to zope.testbrowser 5.x involves quite a number of test changes: some because the test browser has got stricter, and some to work around bugs or misfeatures in the new test browser.  Since there are quite a lot of things to change, it seems helpful to separate out those that can be done in a way that's compatible with both 4.x and 5.x.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:zope.testbrowser-5-prepare into launchpad:master.
diff --git a/lib/lp/blueprints/stories/blueprints/xx-creation.txt b/lib/lp/blueprints/stories/blueprints/xx-creation.txt
index a1802e5..a9e3e31 100644
--- a/lib/lp/blueprints/stories/blueprints/xx-creation.txt
+++ b/lib/lp/blueprints/stories/blueprints/xx-creation.txt
@@ -301,7 +301,7 @@ Canceling creation, brings one back to the blueprints Hoary home.
 
 By default, blueprints are not proposed as series goals:
 
-    >>> control('series goal').control.value
+    >>> bool(control('series goal').control.value)
     False
 
 Pressing the "Register Blueprint" button creates a blueprint targeted to the
@@ -414,7 +414,7 @@ Let's register a blueprint from the Mozilla Firefox 1.0 product series:
 
 By default, blueprints are not proposed as series goals:
 
-    >>> control('series goal').control.value
+    >>> bool(control('series goal').control.value)
     False
 
 Pressing the "Register Blueprint" button creates a blueprint targeted to the
diff --git a/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt b/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt
index 3354e8d..22fddcb 100644
--- a/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt
+++ b/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt
@@ -260,7 +260,7 @@ We can also edit the attachment details, let's navigate to that page.
 
     >>> import re
     >>> user_browser.open('http://bugs.launchpad.test/firefox/+bug/1')
-    >>> user_browser.getLink(url=re.compile(r'[+]attachment/\d+$')).click()
+    >>> user_browser.getLink(url=re.compile(r'.*/\+attachment/\d+$')).click()
     >>> user_browser.url
     'http://bugs.launchpad.test/firefox/+bug/1/+attachment/...'
 
@@ -290,7 +290,7 @@ whitespace to test that's correctly stripped)...
 
 We can edit the attachment to be a patch.
 
-    >>> user_browser.getLink(url=re.compile(r'[+]attachment/\d+$')).click()
+    >>> user_browser.getLink(url=re.compile(r'.*/\+attachment/\d+$')).click()
     >>> patch_control = user_browser.getControl(
     ...     'This attachment contains a solution (patch) for this bug')
     >>> patch_control.selected = True
diff --git a/lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt b/lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt
index 2db3262..aeb9393 100644
--- a/lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt
+++ b/lib/lp/bugs/stories/bugattachments/xx-delete-bug-attachment.txt
@@ -36,7 +36,7 @@ If we go to the attachment edit page, there's an option to delete the
 attachment.
 
     >>> import re
-    >>> user_browser.getLink(url=re.compile(r'[+]attachment/\d+$')).click()
+    >>> user_browser.getLink(url=re.compile(r'.*/\+attachment/\d+$')).click()
     >>> print(user_browser.title)
     Bug #2...
     >>> user_browser.getControl('Delete Attachment') is not None
diff --git a/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.txt b/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.txt
index 11eb253..52e892b 100644
--- a/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.txt
+++ b/lib/lp/bugs/stories/bugtask-management/xx-bug-privileged-statuses.txt
@@ -38,15 +38,12 @@ those statuses are not shown in the UI:
     >>> print(status_control.displayValue)
     ['Confirmed']
 
-    >>> status_control.displayValue = ["Won't Fix"]
-    Traceback (most recent call last):
-    ...
-    ItemNotFoundError: Won't Fix
-
-    >>> status_control.displayValue = ["Triaged"]
-    Traceback (most recent call last):
-    ...
-    ItemNotFoundError: Triaged
+    >>> 'Confirmed' in status_control.displayOptions
+    True
+    >>> "Won't Fix" in status_control.displayOptions
+    False
+    >>> 'Triaged' in status_control.displayOptions
+    False
 
 == Bug Supervisor ==
 
diff --git a/lib/lp/bugs/stories/guided-filebug/xx-bug-reporting-guidelines.txt b/lib/lp/bugs/stories/guided-filebug/xx-bug-reporting-guidelines.txt
index 94edcd6..03484d4 100644
--- a/lib/lp/bugs/stories/guided-filebug/xx-bug-reporting-guidelines.txt
+++ b/lib/lp/bugs/stories/guided-filebug/xx-bug-reporting-guidelines.txt
@@ -200,7 +200,7 @@ bug reporting guidelines can be changed, but admins do.
     >>> def extract_text_from_link(link):
     ...     pass
 
-    >>> edit_url_re = re.compile('/[+]edit$')
+    >>> edit_url_re = re.compile('.*/\+edit$')
     >>> for context_name, context_path, view in contexts:
     ...     overview_url = 'http://launchpad.test/%s' % (context_path,)
     ...     print('* ' + context_name)
diff --git a/lib/lp/buildmaster/stories/xx-builder-page.txt b/lib/lp/buildmaster/stories/xx-builder-page.txt
index bde5653..fed6bf4 100644
--- a/lib/lp/buildmaster/stories/xx-builder-page.txt
+++ b/lib/lp/buildmaster/stories/xx-builder-page.txt
@@ -132,7 +132,7 @@ Other administration fields are available on the 'Change details' form
 as currently administrators are the only users with permission to use the
 Edit page:
 
-    >>> cprov_browser.getControl(name="field.manual").value
+    >>> bool(cprov_browser.getControl(name="field.manual").value)
     False
 
     >>> cprov_browser.getControl(name="field.vm_host").value
diff --git a/lib/lp/code/browser/tests/test_branch.py b/lib/lp/code/browser/tests/test_branch.py
index 5a173cb..4c9f473 100644
--- a/lib/lp/code/browser/tests/test_branch.py
+++ b/lib/lp/code/browser/tests/test_branch.py
@@ -1306,11 +1306,13 @@ class TestBranchDiffView(BrowserTestCase):
         hosting_fixture = self.useFixture(BranchHostingFixture())
         person = self.factory.makePerson()
         branch = self.factory.makeBranch(owner=person)
-        e = self.assertRaises(
-            HTTPError, self.getUserBrowser,
-            canonical_url(branch) + "/+diff/2/1")
-        self.assertEqual(401, e.code)
-        self.assertEqual("Proxying of branch diffs is disabled.\n", e.read())
+        branch_url = canonical_url(branch)
+        browser = self.getUserBrowser()
+        browser.raiseHttpErrors = False
+        browser.open(branch_url + "/+diff/2/1")
+        self.assertEqual(401, int(browser.headers["Status"].split(" ", 1)[0]))
+        self.assertEqual(
+            "Proxying of branch diffs is disabled.\n", browser.contents)
         self.assertEqual([], hosting_fixture.getDiff.calls)
 
     def test_render(self):
diff --git a/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt b/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt
index 5a812f5..07a4613 100644
--- a/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt
+++ b/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt
@@ -46,7 +46,8 @@ The distribution's registrant can access the page and change the usage.
     LAUNCHPAD
     >>> print registrant.getControl(name='field.answers_usage').value[0]
     LAUNCHPAD
-    >>> print registrant.getControl(name='field.require_virtualized').value
+    >>> print bool(
+    ...     registrant.getControl(name='field.require_virtualized').value)
     False
     >>> print registrant.getControl(name='field.processors').value
     ['386', 'amd64', 'hppa']
diff --git a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
index 34ab34c..f83f7e5 100644
--- a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
+++ b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
@@ -324,7 +324,8 @@ On a mad whim they decide to de-activate the key they just imported.
 
 Coming to their senses, they ask for a re-validation of the key.
 
-    >>> browser.getControl(name="REACTIVATE_GPGKEY").value = ['3']
+    >>> browser.getControl(name="REACTIVATE_GPGKEY").value = [
+    ...     '447DBF38C4F9C4ED752246B77D88913717B05A8F']
     >>> browser.getControl('Reactivate Key').click()
 
     >>> print_feedback_messages(browser.contents)
diff --git a/lib/lp/registry/stories/mailinglists/subscriptions.txt b/lib/lp/registry/stories/mailinglists/subscriptions.txt
index f1f7c3f..c0a3408 100644
--- a/lib/lp/registry/stories/mailinglists/subscriptions.txt
+++ b/lib/lp/registry/stories/mailinglists/subscriptions.txt
@@ -217,8 +217,7 @@ Now Jdub can apply for team membership and mailing list access.
     >>> browser.url
     'http://launchpad.test/~rosetta-admins/+join'
 
-    >>> browser.getControl(name='field.mailinglist_subscribe').value = [
-    ...     'checked']
+    >>> browser.getControl(name='field.mailinglist_subscribe').value = True
     >>> browser.getControl(name='field.actions.join').click()
     >>> browser.url
     'http://launchpad.test/~rosetta-admins'
@@ -595,7 +594,8 @@ lists will not have the box checked.
 
     >>> browser.open('http://launchpad.test/~rosetta-admins')
     >>> browser.getLink('Join the team').click()
-    >>> print browser.getControl(name='field.mailinglist_subscribe').value
+    >>> print bool(
+    ...     browser.getControl(name='field.mailinglist_subscribe').value)
     False
 
     # Restore James' setting.
diff --git a/lib/lp/registry/stories/milestone/object-milestones.txt b/lib/lp/registry/stories/milestone/object-milestones.txt
index f0752f1..d1ef248 100644
--- a/lib/lp/registry/stories/milestone/object-milestones.txt
+++ b/lib/lp/registry/stories/milestone/object-milestones.txt
@@ -322,7 +322,7 @@ We'll use a specific URL pattern to avoid matching unrelated links.
 Let's start with the first bug task:
 
     >>> import re
-    >>> edit_status_url = re.compile(r'1.0/\+bug/[0-9]+/\+editstatus')
+    >>> edit_status_url = re.compile(r'.*/1.0/\+bug/[0-9]+/\+editstatus')
     >>> browser.getLink(url=edit_status_url).click()
 
 Completing the "edit status" form allows us to add the bug task to the
@@ -339,7 +339,7 @@ milestone:
 Now we'll add the second bug task to the test milestone, using the same
 method. However this time we'll use a different importance:
 
-    >>> edit_status_url = re.compile(r'2.0/\+bug/[0-9]+/\+editstatus')
+    >>> edit_status_url = re.compile(r'.*/2.0/\+bug/[0-9]+/\+editstatus')
     >>> browser.getLink(url=edit_status_url).click()
     >>> browser.getControl('Milestone').displayValue = [milestone]
     >>> browser.getControl('Importance').value = ['High']
diff --git a/lib/lp/registry/stories/product/xx-product-add.txt b/lib/lp/registry/stories/product/xx-product-add.txt
index b2841b2..b418979 100644
--- a/lib/lp/registry/stories/product/xx-product-add.txt
+++ b/lib/lp/registry/stories/product/xx-product-add.txt
@@ -142,7 +142,7 @@ interested in being the project maintainer for the long run.
     >>> user_browser.getControl('Continue').click()
     >>> user_browser.getControl('Python Licence').click()
     >>> disclaim = user_browser.getControl(name='field.disclaim_maintainer')
-    >>> disclaim.value = ['checked']
+    >>> disclaim.value = True
     >>> user_browser.getControl('Complete Registration').click()
 
 Sample person is shown as the registrant but the maintainer is now
diff --git a/lib/lp/registry/stories/team/xx-team-home.txt b/lib/lp/registry/stories/team/xx-team-home.txt
index b75b1e2..006b1a4 100644
--- a/lib/lp/registry/stories/team/xx-team-home.txt
+++ b/lib/lp/registry/stories/team/xx-team-home.txt
@@ -159,7 +159,7 @@ address:
 As teams do not have OpenID Logins, there is no link in the Contact
 details section for help.
 
-    >>> sample_browser.getLink('(What\xe2\x80\x99s\xc2\xa0this?)')
+    >>> sample_browser.getLink('OpenID help')
     Traceback (most recent call last):
      ...
     LinkNotFoundError
diff --git a/lib/lp/services/webapp/login.py b/lib/lp/services/webapp/login.py
index 0dcb795..b9076b1 100644
--- a/lib/lp/services/webapp/login.py
+++ b/lib/lp/services/webapp/login.py
@@ -225,6 +225,8 @@ class OpenIDLogin(LaunchpadView):
         return_to = urlappend(trust_root, '+openid-callback')
         return_to = "%s?%s" % (return_to, starting_url)
         form_html = self.openid_request.htmlMarkup(trust_root, return_to)
+        self.request.response.setHeader(
+            'Content-Type', 'text/html; charset="utf-8"')
 
         # The consumer.begin() call above will insert rows into the
         # OpenIDAssociations table, but since this will be a GET request, the
diff --git a/lib/lp/services/webapp/tests/test_error.py b/lib/lp/services/webapp/tests/test_error.py
index 7f52168..4485f09 100644
--- a/lib/lp/services/webapp/tests/test_error.py
+++ b/lib/lp/services/webapp/tests/test_error.py
@@ -147,11 +147,13 @@ class TestDatabaseErrorViews(TestCase):
                 super(Disconnects, self).__init__(
                     ('DisconnectionError', message))
 
+        browser = Browser()
+        browser.raiseHttpErrors = False
         with CaptureOops() as oopses:
-            error = self.getHTTPError(url)
-        self.assertEqual(503, error.code)
-        self.assertThat(error.read(),
-                        Contains(DisconnectionErrorView.reason))
+            browser.open(url)
+        self.assertEqual(503, int(browser.headers['Status'].split(' ', 1)[0]))
+        self.assertThat(
+            browser.contents, Contains(DisconnectionErrorView.reason))
         self.assertThat(
             [(oops['type'], oops['value'].split('\n')[0])
              for oops in oopses.oopses],
@@ -168,10 +170,10 @@ class TestDatabaseErrorViews(TestCase):
 
         # We keep seeing the correct exception on subsequent requests.
         with CaptureOops() as oopses:
-            error = self.getHTTPError(url)
-        self.assertEqual(503, error.code)
-        self.assertThat(error.read(),
-                        Contains(DisconnectionErrorView.reason))
+            browser.open(url)
+        self.assertEqual(503, int(browser.headers['Status'].split(' ', 1)[0]))
+        self.assertThat(
+            browser.contents, Contains(DisconnectionErrorView.reason))
         self.assertThat(
             [(oops['type'], oops['value'].split('\n')[0])
              for oops in oopses.oopses],
@@ -198,10 +200,10 @@ class TestDatabaseErrorViews(TestCase):
         cur.execute("RESUME " + dbname)
 
         with CaptureOops() as oopses:
-            error = self.getHTTPError(url)
-        self.assertEqual(503, error.code)
-        self.assertThat(error.read(),
-                        Contains(DisconnectionErrorView.reason))
+            browser.open(url)
+        self.assertEqual(503, int(browser.headers['Status'].split(' ', 1)[0]))
+        self.assertThat(
+            browser.contents, Contains(DisconnectionErrorView.reason))
         self.assertThat(
             [(oops['type'], oops['value'].split('\n')[0])
              for oops in oopses.oopses],
@@ -209,10 +211,10 @@ class TestDatabaseErrorViews(TestCase):
 
         # A second request doesn't log any OOPSes.
         with CaptureOops() as oopses:
-            error = self.getHTTPError(url)
-        self.assertEqual(503, error.code)
-        self.assertThat(error.read(),
-                        Contains(DisconnectionErrorView.reason))
+            browser.open(url)
+        self.assertEqual(503, int(browser.headers['Status'].split(' ', 1)[0]))
+        self.assertThat(
+            browser.contents, Contains(DisconnectionErrorView.reason))
         self.assertEqual(
             [],
             [(oops['type'], oops['value'].split('\n')[0])
@@ -240,10 +242,14 @@ class TestDatabaseErrorViews(TestCase):
             "error-test"))
 
         url = 'http://launchpad.test/error-test'
-        error = self.getHTTPError(url)
-        self.assertEqual(httplib.SERVICE_UNAVAILABLE, error.code)
-        self.assertThat(error.read(),
-                        Contains(OperationalErrorView.reason))
+        browser = Browser()
+        browser.raiseHttpErrors = False
+        browser.open(url)
+        self.assertEqual(
+            httplib.SERVICE_UNAVAILABLE,
+            int(browser.headers['Status'].split(' ', 1)[0]))
+        self.assertThat(
+            browser.contents, Contains(OperationalErrorView.reason))
 
     def test_operationalerror_view(self):
         request = LaunchpadTestRequest()
diff --git a/lib/lp/snappy/tests/test_snapbuild.py b/lib/lp/snappy/tests/test_snapbuild.py
index aa69ae3..67e2be1 100644
--- a/lib/lp/snappy/tests/test_snapbuild.py
+++ b/lib/lp/snappy/tests/test_snapbuild.py
@@ -11,10 +11,7 @@ from datetime import (
     datetime,
     timedelta,
     )
-from urllib2 import (
-    HTTPError,
-    urlopen,
-    )
+from urllib2 import urlopen
 
 from fixtures import FakeLogger
 from pymacaroons import Macaroon
@@ -802,9 +799,9 @@ class TestSnapBuildWebservice(TestCaseWithFactory):
         self.assertEqual(5000, build["score"])
 
     def assertCanOpenRedirectedUrl(self, browser, url):
-        redirection = self.assertRaises(HTTPError, browser.open, url)
-        self.assertEqual(303, redirection.code)
-        urlopen(redirection.hdrs["Location"]).close()
+        browser.open(url)
+        self.assertEqual(303, int(browser.headers["Status"].split(" ", 1)[0]))
+        urlopen(browser.headers["Location"]).close()
 
     def test_logs(self):
         # API clients can fetch the build and upload logs.
@@ -815,6 +812,7 @@ class TestSnapBuildWebservice(TestCaseWithFactory):
         logout()
         build = self.webservice.get(build_url).jsonBody()
         browser = self.getNonRedirectingBrowser(user=self.person)
+        browser.raiseHttpErrors = False
         self.assertIsNotNone(build["build_log_url"])
         self.assertCanOpenRedirectedUrl(browser, build["build_log_url"])
         self.assertIsNotNone(build["upload_log_url"])
@@ -834,6 +832,7 @@ class TestSnapBuildWebservice(TestCaseWithFactory):
         self.assertEqual(200, response.status)
         self.assertContentEqual(file_urls, response.jsonBody())
         browser = self.getNonRedirectingBrowser(user=self.person)
+        browser.raiseHttpErrors = False
         for file_url in file_urls:
             self.assertCanOpenRedirectedUrl(browser, file_url)
 
diff --git a/lib/lp/soyuz/stories/ppa/xx-ppa-workflow.txt b/lib/lp/soyuz/stories/ppa/xx-ppa-workflow.txt
index f22cd6b..95e5e11 100644
--- a/lib/lp/soyuz/stories/ppa/xx-ppa-workflow.txt
+++ b/lib/lp/soyuz/stories/ppa/xx-ppa-workflow.txt
@@ -372,10 +372,10 @@ build on a virtualized builder.
 
     >>> admin_browser.getControl(name="field.enabled").value
     True
-    >>> admin_browser.getControl(name="field.private").value
+    >>> bool(admin_browser.getControl(name="field.private").value)
     False
-    >>> admin_browser.getControl(
-    ...     name="field.suppress_subscription_notifications").value
+    >>> bool(admin_browser.getControl(
+    ...     name="field.suppress_subscription_notifications").value)
     False
     >>> admin_browser.getControl(name="field.require_virtualized").value
     True
@@ -730,12 +730,12 @@ Going back to the edit page, we can see the publish flag was cleared:
 
     >>> no_priv_browser.open(
     ...     "http://launchpad.test/~no-priv/+archive/ppa/+edit";)
-    >>> print(no_priv_browser.getControl(name='field.publish').value)
+    >>> bool(no_priv_browser.getControl(name='field.publish').value)
     False
 
 Once we re-enable the PPA the "disabled" warning message will be gone.
 
-    >>> print(no_priv_browser.getControl(name='field.enabled').value)
+    >>> bool(no_priv_browser.getControl(name='field.enabled').value)
     False
 
     >>> no_priv_browser.getControl(name='field.enabled').value = True
diff --git a/lib/lp/soyuz/tests/test_livefsbuild.py b/lib/lp/soyuz/tests/test_livefsbuild.py
index 13499bc..987c6b1 100644
--- a/lib/lp/soyuz/tests/test_livefsbuild.py
+++ b/lib/lp/soyuz/tests/test_livefsbuild.py
@@ -11,10 +11,7 @@ from datetime import (
     datetime,
     timedelta,
     )
-from urllib2 import (
-    HTTPError,
-    urlopen,
-    )
+from urllib2 import urlopen
 
 import pytz
 from zope.component import getUtility
@@ -453,9 +450,9 @@ class TestLiveFSBuildWebservice(TestCaseWithFactory):
         self.assertEqual(5000, build["score"])
 
     def assertCanOpenRedirectedUrl(self, browser, url):
-        redirection = self.assertRaises(HTTPError, browser.open, url)
-        self.assertEqual(303, redirection.code)
-        urlopen(redirection.hdrs["Location"]).close()
+        browser.open(url)
+        self.assertEqual(303, int(browser.headers["Status"].split(" ", 1)[0]))
+        urlopen(browser.headers["Location"]).close()
 
     def test_logs(self):
         # API clients can fetch the build and upload logs.
@@ -466,6 +463,7 @@ class TestLiveFSBuildWebservice(TestCaseWithFactory):
         logout()
         build = self.webservice.get(build_url).jsonBody()
         browser = self.getNonRedirectingBrowser(user=self.person)
+        browser.raiseHttpErrors = False
         self.assertIsNotNone(build["build_log_url"])
         self.assertCanOpenRedirectedUrl(browser, build["build_log_url"])
         self.assertIsNotNone(build["upload_log_url"])
@@ -486,5 +484,6 @@ class TestLiveFSBuildWebservice(TestCaseWithFactory):
         self.assertEqual(200, response.status)
         self.assertContentEqual(file_urls, response.jsonBody())
         browser = self.getNonRedirectingBrowser(user=self.person)
+        browser.raiseHttpErrors = False
         for file_url in file_urls:
             self.assertCanOpenRedirectedUrl(browser, file_url)
diff --git a/lib/lp/soyuz/tests/test_packageupload.py b/lib/lp/soyuz/tests/test_packageupload.py
index 3fe2e73..5f78fe2 100644
--- a/lib/lp/soyuz/tests/test_packageupload.py
+++ b/lib/lp/soyuz/tests/test_packageupload.py
@@ -7,10 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
 
 from datetime import timedelta
 import io
-from urllib2 import (
-    HTTPError,
-    urlopen,
-    )
+from urllib2 import urlopen
 
 from debian.deb822 import Changes
 from lazr.restfulclient.errors import (
@@ -1044,9 +1041,9 @@ class TestPackageUploadWebservice(TestCaseWithFactory):
         return upload, self.load(upload, person)
 
     def assertCanOpenRedirectedUrl(self, browser, url):
-        redirection = self.assertRaises(HTTPError, browser.open, url)
-        self.assertEqual(303, redirection.code)
-        urlopen(redirection.hdrs["Location"]).close()
+        browser.open(url)
+        self.assertEqual(303, int(browser.headers["Status"].split(" ", 1)[0]))
+        urlopen(browser.headers["Location"]).close()
 
     def assertRequiresEdit(self, method_name, **kwargs):
         """Test that a web service queue method requires launchpad.Edit."""
@@ -1128,6 +1125,7 @@ class TestPackageUploadWebservice(TestCaseWithFactory):
         self.assertContentEqual(source_file_urls, ws_source_file_urls)
 
         browser = self.getNonRedirectingBrowser(user=person)
+        browser.raiseHttpErrors = False
         for ws_source_file_url in ws_source_file_urls:
             self.assertCanOpenRedirectedUrl(browser, ws_source_file_url)
         self.assertCanOpenRedirectedUrl(browser, ws_upload.changes_file_url)
@@ -1217,6 +1215,7 @@ class TestPackageUploadWebservice(TestCaseWithFactory):
         self.assertContentEqual(binary_file_urls, ws_binary_file_urls)
 
         browser = self.getNonRedirectingBrowser(user=person)
+        browser.raiseHttpErrors = False
         for ws_binary_file_url in ws_binary_file_urls:
             self.assertCanOpenRedirectedUrl(browser, ws_binary_file_url)
         self.assertCanOpenRedirectedUrl(browser, ws_upload.changes_file_url)
@@ -1380,6 +1379,7 @@ class TestPackageUploadWebservice(TestCaseWithFactory):
         self.assertContentEqual(custom_file_urls, ws_custom_file_urls)
 
         browser = self.getNonRedirectingBrowser(user=person)
+        browser.raiseHttpErrors = False
         for ws_custom_file_url in ws_custom_file_urls:
             self.assertCanOpenRedirectedUrl(browser, ws_custom_file_url)
         self.assertCanOpenRedirectedUrl(browser, ws_upload.changes_file_url)
diff --git a/lib/lp/translations/stories/standalone/xx-pofile-translate-message-filtering.txt b/lib/lp/translations/stories/standalone/xx-pofile-translate-message-filtering.txt
index c6dc1ff..b7cb1c1 100644
--- a/lib/lp/translations/stories/standalone/xx-pofile-translate-message-filtering.txt
+++ b/lib/lp/translations/stories/standalone/xx-pofile-translate-message-filtering.txt
@@ -201,8 +201,7 @@ navigation.
     1 ... 10  of 22 results
 
     >>> user_browser.getControl(
-    ...     name='msgset_1_en_AU_translation_0_new_checkbox').value = [
-    ...         'msgset_1_en_AU_translation_0_new']
+    ...     name='msgset_1_en_AU_translation_0_new_checkbox').value = True
     >>> user_browser.getControl(
     ...     name='msgset_1_en_AU_translation_0_new').value = 'fnord'
     >>> user_browser.getControl('Save & Continue').click()
diff --git a/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt b/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
index 500a58c..bf9852a 100644
--- a/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
+++ b/lib/lp/translations/stories/standalone/xx-potemplate-admin.txt
@@ -59,7 +59,7 @@ a Rosetta Expert to administer it.
     ''
     >>> browser.getControl(name='field.sourcepackageversion').value
     ''
-    >>> browser.getControl(name='field.languagepack').value
+    >>> bool(browser.getControl(name='field.languagepack').value)
     False
     >>> browser.getControl(name='field.path').value
     'po/evolution-2.2.pot'
@@ -105,7 +105,7 @@ an admin to administer it.
     ''
     >>> admin_browser.getControl(name='field.sourcepackageversion').value
     ''
-    >>> admin_browser.getControl(name='field.languagepack').value
+    >>> bool(admin_browser.getControl(name='field.languagepack').value)
     False
     >>> admin_browser.getControl(name='field.path').value
     'po/evolution-2.2.pot'
diff --git a/lib/lp/translations/stories/standalone/xx-potemplate-edit.txt b/lib/lp/translations/stories/standalone/xx-potemplate-edit.txt
index 03665bd..d46ac09 100644
--- a/lib/lp/translations/stories/standalone/xx-potemplate-edit.txt
+++ b/lib/lp/translations/stories/standalone/xx-potemplate-edit.txt
@@ -139,7 +139,7 @@ page.
     >>> browser.getControl(name='field.priority').value
     '100'
 
-    >>> browser.getControl(name='field.iscurrent').value
+    >>> bool(browser.getControl(name='field.iscurrent').value)
     False
 
     >>> browser.getControl(name='field.path').value
diff --git a/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt b/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt
index a15080f..dda582b 100644
--- a/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt
+++ b/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt
@@ -348,7 +348,8 @@ Check for the translator note:
 
 Also check that the alternative language selection is working:
 
-    >>> browser.getControl('Catalan (ca)').click()
+    >>> browser.getControl(name='field.alternative_language').getControl(
+    ...     'Catalan (ca)').click()
     >>> browser.getControl('Change').click()
     >>> browser.url
     'http:/...field.alternative_language=ca...'