← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~deryck/launchpad/windmill-death into lp:launchpad

 

Deryck Hodge has proposed merging lp:~deryck/launchpad/windmill-death into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~deryck/launchpad/windmill-death/+merge/66012

Death to Windmill!  Die happy, no one loved you.  EVER!
-- 
https://code.launchpad.net/~deryck/launchpad/windmill-death/+merge/66012
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~deryck/launchpad/windmill-death into lp:launchpad.
=== modified file 'Makefile'
--- Makefile	2011-06-08 00:56:51 +0000
+++ Makefile	2011-06-27 15:56:40 +0000
@@ -55,10 +55,9 @@
     bin/fl-record bin/fl-run-bench bin/fl-run-test bin/googletestservice \
     bin/i18ncompile bin/i18nextract bin/i18nmergeall bin/i18nstats \
     bin/harness bin/iharness bin/ipy bin/jsbuild bin/jslint bin/jssize \
-    bin/jstest bin/killservice bin/kill-test-services bin/lint.sh \
-    bin/lp-windmill bin/retest bin/run bin/sprite-util \
-    bin/start_librarian bin/stxdocs bin/tags bin/test bin/tracereport \
-    bin/twistd bin/update-download-cache bin/windmill
+    bin/jstest bin/killservice bin/kill-test-services bin/lint.sh bin/retest \
+    bin/run bin/sprite-util bin/start_librarian bin/stxdocs bin/tags \
+    bin/test bin/tracereport bin/twistd bin/update-download-cache
 
 BUILDOUT_TEMPLATES = buildout-templates/_pythonpath.py.in
 

=== modified file 'buildout.cfg'
--- buildout.cfg	2011-03-23 14:39:55 +0000
+++ buildout.cfg	2011-06-27 15:56:40 +0000
@@ -40,7 +40,6 @@
 [scripts]
 recipe = z3c.recipe.scripts
 eggs = lp
-    windmill
     funkload
     zc.zservertracelog
 # XXX gary 2009-5-12 bug 375751:
@@ -56,8 +55,6 @@
     main('${configuration:instance_name}') # Initializes LP environment.
 entry-points = stxdocs=zope.configuration.stxdocs:main
     googletestservice=lp.services.googlesearch.googletestservice:main
-    windmill=windmill.bin.windmill_bin:main
-    lp-windmill=lp.scripts.utilities.lpwindmill:main
     jsbuild=lazr.js.build:main
     jslint=lazr.js.jslint:main
     tracereport=zc.zservertracelog.tracereport:main

=== removed file 'lib/canonical/launchpad/windmill/__init__.py'
=== removed directory 'lib/canonical/launchpad/windmill/tests'
=== removed file 'lib/canonical/launchpad/windmill/tests/__init__.py'
--- lib/canonical/launchpad/windmill/tests/__init__.py	2010-07-26 20:06:23 +0000
+++ lib/canonical/launchpad/windmill/tests/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).

=== removed file 'lib/canonical/launchpad/windmill/tests/test_widgets.py'
--- lib/canonical/launchpad/windmill/tests/test_widgets.py	2011-02-10 04:00:00 +0000
+++ lib/canonical/launchpad/windmill/tests/test_widgets.py	1970-01-01 00:00:00 +0000
@@ -1,66 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Tests for the Windmill test doubles themselves."""
-
-__metaclass__ = type
-
-from mocker import (
-    KWARGS,
-    Mocker,
-    )
-
-from lp.testing import TestCase
-from lp.testing.windmill.widgets import OnPageWidget
-
-
-class TestOnPageWidget(TestCase):
-
-    """Tests for the OnPageWidget JavaScript widgets helper."""
-
-    def test_valid_widget_xpath(self):
-        widget = OnPageWidget(None, 'widget')
-        self.assertEqual(u"//div[contains(@class, 'widget ')]", widget.xpath)
-
-    def test_visible_xpath_property(self):
-        widget = OnPageWidget(None, 'widget')
-        self.assertEqual(u"//div[contains(@class, 'widget ') "
-                         "and not(contains(@class, 'widget-hidden'))]",
-                         widget.visible_xpath)
-
-    def test_hidden_xpath_property(self):
-        widget = OnPageWidget(None, 'widget')
-        self.assertEqual(u"//div[contains(@class, 'widget ') "
-                         "and contains(@class, 'widget-hidden')]",
-                         widget.hidden_xpath)
-
-
-class TestWidgetVisibility(TestCase):
-
-    def setUp(self):
-        super(TestWidgetVisibility, self).setUp()
-        self.mocker = Mocker()
-
-    def make_client_with_expected_visibility(self, expected_visibility_attr):
-        widget = OnPageWidget(None, 'widget')
-        expected_value = getattr(widget, expected_visibility_attr)
-
-        # Set up the Mock
-        client = self.mocker.mock()
-
-        # Expectation
-        client.waits.forElement(KWARGS, xpath=expected_value)
-
-        return client
-
-    def test_widget_visible_check(self):
-        client = self.make_client_with_expected_visibility('visible_xpath')
-        with self.mocker:
-            widget = OnPageWidget(client, 'widget')
-            widget.should_be_visible()
-
-    def test_widget_hidden_check(self):
-        client = self.make_client_with_expected_visibility('hidden_xpath')
-        with self.mocker:
-            widget = OnPageWidget(client, 'widget')
-            widget.should_be_hidden()

=== modified file 'lib/canonical/testing/layers.py'
--- lib/canonical/testing/layers.py	2011-06-09 15:37:18 +0000
+++ lib/canonical/testing/layers.py	2011-06-27 15:56:40 +0000
@@ -25,7 +25,6 @@
 __all__ = [
     'AppServerLayer',
     'BaseLayer',
-    'BaseWindmillLayer',
     'DatabaseFunctionalLayer',
     'DatabaseLayer',
     'ExperimentalLaunchpadZopelessLayer',
@@ -81,9 +80,6 @@
 
 from lazr.restful.utils import safe_hasattr
 
-from windmill.bin.admin_lib import (
-    start_windmill, teardown as windmill_teardown)
-
 import zope.app.testing.functional
 import zope.publisher.publish
 from zope.app.publication.httpfactory import chooseClasses
@@ -1980,133 +1976,5 @@
         LayerProcessController.postTestInvariants()
 
 
-class BaseWindmillLayer(AppServerLayer):
-    """Layer for Windmill tests.
-
-    This layer shouldn't be used directly. A subclass needs to be
-    created specifying which base URL to use (e.g.
-    http://bugs.launchpad.dev:8085/).
-    """
-
-    facet = None
-    base_url = None
-    shell_objects = None
-    config_file = None
-
-    @classmethod
-    @profiled
-    def setUp(cls):
-        if cls.base_url is None:
-            # Only do the setup if we're in a subclass that defines
-            # base_url. With no base_url, we can't create the config
-            # file windmill needs.
-            return
-
-        cls._fixStandardInputFileno()
-        cls._configureWindmillLogging()
-        cls._configureWindmillStartup()
-
-        # Tell windmill to start its browser and server.  Our testrunner will
-        # keep going, passing commands to the server for execution.
-        cls.shell_objects = start_windmill()
-
-        # Patch the config to provide the port number and not use https.
-        sites = (
-            (('vhost.%s' % sitename,
-            'rooturl: %s/' % cls.appserver_root_url(sitename))
-            for sitename in ['mainsite', 'answers', 'blueprints', 'bugs',
-                            'code', 'testopenid', 'translations']))
-        for site in sites:
-            config.push('windmillsettings', "\n[%s]\n%s\n" % site)
-        allvhosts.reload()
-
-    @classmethod
-    @profiled
-    def tearDown(cls):
-        if cls.shell_objects is not None:
-            windmill_teardown(cls.shell_objects)
-        if cls.config_file is not None:
-            # Close the file so that it gets deleted.
-            cls.config_file.close()
-        config.reloadConfig()
-        reset_logging()
-        # XXX: deryck 2011-01-28 bug=709438
-        # Windmill mucks about with the default timeout and this is
-        # a fix until the library itself can be cleaned up.
-        socket.setdefaulttimeout(None)
-
-    @classmethod
-    @profiled
-    def testSetUp(cls):
-        # Left-over threads should be harmless, since they should all
-        # belong to Windmill, which will be cleaned up on layer
-        # tear down.
-        BaseLayer.disable_thread_check = True
-        socket.setdefaulttimeout(120)
-
-    @classmethod
-    @profiled
-    def testTearDown(cls):
-        # To play nice with Windmill layers, we need to reset
-        # the socket timeout default in this method, too.
-        socket.setdefaulttimeout(None)
-
-    @classmethod
-    def _fixStandardInputFileno(cls):
-        """Patch the STDIN fileno so Windmill doesn't break."""
-        # If we're running in a bin/test sub-process, sys.stdin is
-        # replaced by FakeInputContinueGenerator, which doesn't have a
-        # fileno method. When Windmill starts Firefox,
-        # sys.stdin.fileno() is called, so we add such a method here, to
-        # prevent it from breaking. By returning None, we should ensure
-        # that it doesn't try to use the return value for anything.
-        if not safe_hasattr(sys.stdin, 'fileno'):
-            assert isinstance(sys.stdin, FakeInputContinueGenerator), (
-                "sys.stdin (%r) doesn't have a fileno method." % sys.stdin)
-            sys.stdin.fileno = lambda: None
-
-    @classmethod
-    def _configureWindmillLogging(cls):
-        """Override the default windmill log handling."""
-        if not config.windmill.debug_log:
-            return
-
-        # Add a new log handler to capture all of the windmill testrunner
-        # output. This overrides windmill's own log handling, which we do not
-        # have direct access to.
-        # We'll overwrite the previous log contents to keep the disk usage
-        # low, and because the contents are only meant as an in-situ debugging
-        # aid.
-        filehandler = logging.FileHandler(config.windmill.debug_log, mode='w')
-        filehandler.setLevel(logging.NOTSET)
-        filehandler.setFormatter(
-            logging.Formatter(
-                "%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
-        logging.getLogger('windmill').addHandler(filehandler)
-
-        # Make sure that everything sent to the windmill logger is captured.
-        # This works because windmill configures the root logger for its
-        # purposes, and we are pre-empting that by inserting a new logger one
-        # level higher in the logger chain.
-        logging.getLogger('windmill').setLevel(logging.NOTSET)
-
-    @classmethod
-    def _configureWindmillStartup(cls):
-        """Pass our startup parameters to the windmill server."""
-        # Windmill needs a config file on disk to load its settings from.
-        # There is no way to directly pass settings to the windmill test
-        # driver from out here.
-        config_text = dedent("""\
-            START_FIREFOX = True
-            TEST_URL = '%s/'
-            CONSOLE_LOG_LEVEL = %d
-            """ % (cls.base_url, logging.NOTSET))
-        cls.config_file = tempfile.NamedTemporaryFile(suffix='.py')
-        cls.config_file.write(config_text)
-        # Flush the file so that windmill can read it.
-        cls.config_file.flush()
-        os.environ['WINDMILL_CONFIG_FILE'] = cls.config_file.name
-
-
 class YUITestLayer(FunctionalLayer):
     """The base class for all YUITests cases."""

=== modified file 'lib/canonical/testing/tests/test_layers.py'
--- lib/canonical/testing/tests/test_layers.py	2010-10-22 09:49:44 +0000
+++ lib/canonical/testing/tests/test_layers.py	2011-06-27 15:56:40 +0000
@@ -8,26 +8,10 @@
 
 import threading
 
-from canonical.testing.layers import (
-    BaseLayer,
-    BaseWindmillLayer,
-    DatabaseLayer,
-    )
+from canonical.testing.layers import BaseLayer
 from lp.testing import TestCase
 
 
-class TestBaseWindmillLayer(TestCase):
-
-    layer_to_test = BaseWindmillLayer
-
-    def test_db_reset_between_tests(self):
-        # The db is reset between tests when DatabaseLayer layer's
-        # testSetUp is called, if _reset_between_tests is True.
-        self.assertTrue(
-            issubclass(self.layer_to_test, DatabaseLayer))
-        self.assertTrue(self.layer_to_test._reset_between_tests)
-
-
 class TestThreadWaiting(TestCase):
     layer = BaseLayer
 

=== removed directory 'lib/lp/app/windmill'
=== removed file 'lib/lp/app/windmill/__init__.py'
=== removed file 'lib/lp/app/windmill/testing.py'
--- lib/lp/app/windmill/testing.py	2011-06-08 16:53:47 +0000
+++ lib/lp/app/windmill/testing.py	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Launchpad app specific testing infrastructure for Windmill."""
-
-__metaclass__ = type
-__all__ = [
-    'AppWindmillLayer',
-    ]
-
-
-from canonical.testing.layers import BaseWindmillLayer
-
-
-class AppWindmillLayer(BaseWindmillLayer):
-    """Layer for App Windmill tests."""
-
-    @classmethod
-    def setUp(cls):
-        cls.base_url = cls.appserver_root_url()
-        super(AppWindmillLayer, cls).setUp()

=== removed directory 'lib/lp/app/windmill/tests'
=== removed file 'lib/lp/app/windmill/tests/__init__.py'
=== removed file 'lib/lp/bugs/windmill/__init__.py'
=== removed file 'lib/lp/bugs/windmill/testing.py'
--- lib/lp/bugs/windmill/testing.py	2011-06-08 16:53:47 +0000
+++ lib/lp/bugs/windmill/testing.py	1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Bugs-specific testing infrastructure for Windmill."""
-
-__metaclass__ = type
-__all__ = [
-    'BugsWindmillLayer',
-    ]
-
-
-from canonical.testing.layers import BaseWindmillLayer
-
-
-class BugsWindmillLayer(BaseWindmillLayer):
-    """Layer for Bugs Windmill tests."""
-
-    @classmethod
-    def setUp(cls):
-        cls.facet = 'bugs'
-        cls.base_url = cls.appserver_root_url(cls.facet)
-        super(BugsWindmillLayer, cls).setUp()

=== removed file 'lib/lp/bugs/windmill/tests/__init__.py'
=== modified file 'lib/lp/bugs/windmill/tests/test_bug_also_affects_new_upstream.py'
--- lib/lp/bugs/windmill/tests/test_bug_also_affects_new_upstream.py	2011-03-29 07:10:40 +0000
+++ lib/lp/bugs/windmill/tests/test_bug_also_affects_new_upstream.py	2011-06-27 15:56:40 +0000
@@ -26,16 +26,6 @@
                             '%s/tomcat/+bug/3/+choose-affected-product'
                             % BugsWindmillLayer.base_url)
 
-    def test_bug_also_affects_picker(self):
-        test_bug_also_affects_picker = FormPickerWidgetTest(
-            name='test_bug_also_affects',
-            url=self.choose_affected_url,
-            short_field_name='product',
-            search_text='firefox',
-            result_index=1,
-            new_value='firefox')
-        test_bug_also_affects_picker()
-
     def test_bug_also_affects_register_link(self):
         """Test that picker shows "Register it" link.
 

=== modified file 'lib/lp/bugs/windmill/tests/test_bug_inline_assignment.py'
--- lib/lp/bugs/windmill/tests/test_bug_inline_assignment.py	2011-05-13 13:24:59 +0000
+++ lib/lp/bugs/windmill/tests/test_bug_inline_assignment.py	2011-06-27 15:56:40 +0000
@@ -65,31 +65,3 @@
         self.client.asserts.assertTextIn(
             xpath=CONFIRMATION,
             validator="Fred did not previously have any assigned bugs")
-
-    def test_no_picker_for_anonymous_users(self):
-        # No assignee picker is shown for an anonymous user.
-
-        client, start_url = self.getClientForAnonymous("/firefox/+bug/1")
-
-        HIDDEN_ASSIGN_BUTTON = (u"//*[@id='affected-software']//tr//td[5]" +
-            "//button[contains(@class,'yui3-activator-act') and "
-            "contains(@class,'yui3-activator-hidden')]")
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertNode(xpath=HIDDEN_ASSIGN_BUTTON)
-
-    def test_no_search_widget_for_teamless_users(self):
-        # Teamless unprivileged users can only assign themselves, so no
-        # search widget is shown.
-
-        product = self.factory.makeProduct(
-            bug_supervisor=self.factory.makePerson())
-        bug = self.factory.makeBug(product=product)
-        transaction.commit()
-        client, start_url = self.getClientFor(
-            canonical_url(bug, force_local_path=True), lpuser.NO_PRIV)
-
-        self.openAssigneePicker(client)
-
-        # Ensure that there is no non-hidden picker search widget.
-        client.asserts.assertNotNode(
-            xpath=full_picker_element_xpath(VISIBLE_PICKER_SEARCH))

=== removed file 'lib/lp/bugs/windmill/tests/test_bug_inline_subscriber.py'
--- lib/lp/bugs/windmill/tests/test_bug_inline_subscriber.py	2011-03-29 05:59:29 +0000
+++ lib/lp/bugs/windmill/tests/test_bug_inline_subscriber.py	1970-01-01 00:00:00 +0000
@@ -1,249 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-import unittest
-
-from lp.bugs.windmill.testing import BugsWindmillLayer
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import lpuser
-from lp.testing.windmill.constants import (
-    FOR_ELEMENT,
-    PAGE_LOAD,
-    SLEEP,
-    )
-
-
-SUBSCRIPTION_LINK = u'//div[@id="portlet-subscribers"]/div/div/a'
-PERSON_LINK = u'//div[@id="subscribers-links"]/div/a[@name="%s"]'
-
-
-class TestInlineSubscribing(WindmillTestCase):
-
-    layer = BugsWindmillLayer
-    suite_name = 'Inline bug page subscribers test'
-
-    def test_inline_subscriber(self):
-        # This test fails intermittently.  See bug #516781.
-        """Test inline subscribing on bugs pages.
-
-        This test makes sure that subscribing and unsubscribing
-        from a bug works inline on a bug page.
-        """
-        client, start_url = self.getClientFor('/bugs/11',
-            user=lpuser.SAMPLE_PERSON)
-
-        # Ensure the subscriber's portlet has finished loading.
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-
-        # "Sample Person" should not be subscribed initially.
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Subscribe')
-
-        # Subscribe "Sample Person" and check that the subscription
-        # link now reads "Unsubscribe", that the person's name
-        # appears in the subscriber's list, and that the icon
-        # has changed to the remove icon.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Unsubscribe')
-        client.asserts.assertNode(xpath=PERSON_LINK % u'Sample Person')
-        client.asserts.assertProperty(
-            xpath=SUBSCRIPTION_LINK,
-            validator=u'className|remove')
-
-        # Make sure the unsubscribe link also works, that
-        # the person's named is removed from the subscriber's list,
-        # and that the icon has changed to the add icon.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Subscribe')
-        client.asserts.assertProperty(
-            xpath=SUBSCRIPTION_LINK,
-            validator=u'className|add')
-        client.asserts.assertNotNode(xpath=PERSON_LINK % u'Sample Person')
-
-        # Subscribe again in order to check that the minus icon
-        # next to the subscriber's name works as an inline unsubscribe link.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Unsubscribe')
-        client.click(id=u'unsubscribe-icon-subscriber-12')
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Subscribe')
-        client.asserts.assertProperty(
-            xpath=SUBSCRIPTION_LINK,
-            validator=u'className|add')
-        client.asserts.assertNotNode(xpath=PERSON_LINK % u'Sample Person')
-
-        # Test inline subscribing of others by subscribing Ubuntu Team.
-        # To confirm, look for the Ubuntu Team element after subscribing.
-        client.click(link=u'Subscribe someone else')
-        client.waits.forElement(
-            name=u'search', timeout=FOR_ELEMENT)
-        client.type(
-            text=u'ubuntu-team',
-            xpath=u'//div[contains(@class, "yui3-picker ") '
-                   'and not(contains(@class, "yui3-picker-hidden"))]'
-                   '//div[@class="yui3-picker-search-box"]'
-                   '/input[@name="search"]')
-        client.click(
-            xpath=u'//div[contains(@class, "yui3-picker ") '
-                   'and not(contains(@class, "yui3-picker-hidden"))]'
-                   '//div[@class="yui3-picker-search-box"]/button')
-        search_result_xpath = (
-            u'//div[contains(@class, "yui3-picker ") '
-            'and not(contains(@class, "yui3-picker-hidden"))]'
-            '//ul[@class="yui3-picker-results"]/li[1]/span')
-        client.waits.forElement(
-            xpath=search_result_xpath, timeout=FOR_ELEMENT)
-        client.click(xpath=search_result_xpath)
-        client.waits.forElement(
-            xpath=PERSON_LINK % u'Ubuntu Team', timeout=FOR_ELEMENT)
-
-        # If we subscribe the user again,
-        # the icon should still be the person icon.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertProperty(
-            xpath=(PERSON_LINK % u'Sample Person') + '/span',
-            validator=u'className|person')
-
-        # Sample Person is logged in currently. She is not a
-        # member of Ubuntu Team, and so, does not have permission
-        # to unsubscribe the team.
-        client.asserts.assertNotNode(id=u'unsubscribe-icon-subscriber-17')
-
-        # Login Foo Bar who is a member of Ubuntu Team.
-        # After login, wait for the page load and subscribers portlet.
-        client, start_url = self.getClientFor('/bugs/11',
-            user=lpuser.FOO_BAR)
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-
-        # Now test inline unsubscribing of a team, by ensuring
-        # that Ubuntu Team is removed from the subscribers list.
-        client.click(id=u'unsubscribe-icon-subscriber-17')
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertNotNode(xpath=PERSON_LINK % u'Ubuntu Team')
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Unsubscribe')
-        client.asserts.assertProperty(
-            xpath=SUBSCRIPTION_LINK,
-            validator=u'className|remove')
-
-        bug_url = u'%s/bugs/%%s' % BugsWindmillLayer.base_url
-
-        # Test unsubscribing via the remove icon for duplicates.
-        # First, go to bug 6 and subscribe.
-        client.open(url=bug_url % 6)
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Unsubscribe')
-        client.asserts.assertNode(xpath=PERSON_LINK % u'Foo Bar')
-        # Bug 6 is a dupe of bug 5, so go to bug 5 to unsubscribe.
-        client.open(url=bug_url % 5)
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-        client.click(id=u'unsubscribe-icon-subscriber-16')
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Subscribe')
-        client.asserts.assertNotNode(xpath=PERSON_LINK % u'Foo Bar')
-        # Then back to bug 6 to confirm the duplicate is also unsubscribed.
-        client.open(url=bug_url % 6)
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Subscribe')
-        client.asserts.assertNotNode(xpath=PERSON_LINK % u'Foo Bar')
-
-        # Subscribe/Unsubscribe link handling when dealing
-        # with duplicates...
-        #
-        # First test case, ensure unsubscribing works when
-        # dealing with a duplicate and an indirect subscription.
-        # Go to bug 6, the dupe, and subscribe.
-        client, start_url = self.getClientFor('/bugs/6',
-            user=lpuser.SAMPLE_PERSON)
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Unsubscribe')
-        # Now back to bug 5.
-        client.open(url=bug_url % 5)
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-        # Confirm there are 2 subscriber links: one in duplicate subscribers,
-        # and one in indirect subscribers.
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertNode(
-            xpath=(u'//div[@id="subscribers-from-duplicates"]'
-                   '/div/a[@name="Sample Person"]'))
-        client.asserts.assertNode(
-            xpath=(u'//div[@id="subscribers-indirect"]'
-                   '/div/a[text() = "Sample Person"]'))
-        # Clicking "Unsubscribe" successfully removes the duplicate
-        # subscription but the indirect subscription remains.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertNotNode(
-            xpath=(u'//div[@id="subscribers-from-duplicates"]'
-                   '/div/a[@name="Sample Person"]'))
-        client.asserts.assertNode(
-            xpath=(u'//div[@id="subscribers-indirect"]'
-                   '/div/a[text() = "Sample Person"]'))
-
-        # Second test case, confirm duplicate handling is correct between
-        # direct and duplicate subscriptions.  Subscribe directly to bug 5.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Unsubscribe')
-        # Go to bug 6, the dupe, and subscribe.
-        client.open(url=bug_url % 6)
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.waits.forElement(
-            id=u'subscribers-links', timeout=FOR_ELEMENT)
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertText(
-            xpath=SUBSCRIPTION_LINK, validator=u'Unsubscribe')
-        # Now back to bug 5. Confirm there are 2 subscriptions.
-        client.open(url=bug_url % 5)
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.waits.forElement(
-            id='direct-subscriber-12', timeout=FOR_ELEMENT)
-        # The first click unsubscribes the direct subscription, leaving
-        # the duplicate subscription.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertNotNode(
-            xpath=(u'//div[@id="subscribers-links"]'
-                   '/div/a[@name="Sample Person"]'))
-        client.asserts.assertNode(
-            xpath=(u'//div[@id="subscribers-from-duplicates"]'
-                   '/div/a[@name="Sample Person"]'))
-        # The second unsubscribe removes the duplicate, too.
-        client.click(xpath=SUBSCRIPTION_LINK)
-        client.waits.sleep(milliseconds=SLEEP)
-        client.asserts.assertNotNode(
-            xpath=(u'//div[@id="subscribers-from-duplicates"]'
-                   '/div/a[@name="Sample Person"]'))
-
-
-def test_suite():
-    return unittest.TestLoader().loadTestsFromName(__name__)

=== modified file 'lib/lp/bugs/windmill/tests/test_bug_privacy_settings.py'
--- lib/lp/bugs/windmill/tests/test_bug_privacy_settings.py	2011-03-29 05:59:29 +0000
+++ lib/lp/bugs/windmill/tests/test_bug_privacy_settings.py	2011-06-27 15:56:40 +0000
@@ -34,6 +34,7 @@
 
 
 class TestSecurityOverlay(WindmillTestCase):
+    """XXX: This should be split between YUI test and selnium."""
 
     layer = BugsWindmillLayer
     suite_name = "Bug privacy settings test"

=== modified file 'lib/lp/bugs/windmill/tests/test_bug_tags_entry.py'
--- lib/lp/bugs/windmill/tests/test_bug_tags_entry.py	2011-05-12 06:06:35 +0000
+++ lib/lp/bugs/windmill/tests/test_bug_tags_entry.py	2011-06-27 15:56:40 +0000
@@ -19,6 +19,7 @@
 
 
 class TestBugTagsEntry(WindmillTestCase):
+    """XXX: Move to YUI test."""
 
     layer = BugsWindmillLayer
     suite_name = 'Bug tags entry test'

=== removed file 'lib/lp/bugs/windmill/tests/test_filebug_dupe_finder.py'
--- lib/lp/bugs/windmill/tests/test_filebug_dupe_finder.py	2011-03-29 05:59:29 +0000
+++ lib/lp/bugs/windmill/tests/test_filebug_dupe_finder.py	1970-01-01 00:00:00 +0000
@@ -1,115 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-from lp.bugs.windmill.testing import BugsWindmillLayer
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import (
-    constants,
-    lpuser,
-    )
-
-
-FORM_OVERLAY = u'//div[@id="duplicate-overlay-bug-4"]/div'
-FORM_OVERLAY_CANCEL = (
-    u'//div[@id="duplicate-overlay-bug-4"]'
-    '//button[@name="field.actions.cancel"]')
-FORM_OVERLAY_SUBMIT = (
-    u'//div[@id="duplicate-overlay-bug-4"]'
-    '//button[@name="field.actions.this_is_my_bug"]')
-
-# JavaScript expressions for testing.
-FORM_NOT_VISIBLE = (
-    u'element.className.search("yui3-lazr-formoverlay-hidden") != -1')
-FORM_VISIBLE = (
-    u'element.className.search("yui3-lazr-formoverlay-hidden") == -1')
-
-BUG_INFO_HIDDEN = 'style.height|0px'
-BUG_INFO_SHOWN_JS = 'element.style.height != "0px"'
-
-
-class TestDupeFinder(WindmillTestCase):
-
-    layer = BugsWindmillLayer
-    suite_name = "Duplicate bug finder test"
-
-    def test_duplicate_finder(self):
-        """Test the +filebug duplicate finder.
-
-        The duplicate finder should show a simple view of possible
-        duplicates for a bug, with an expander that allows the user to view
-        more information if they wish.
-        """
-
-        # Go to the +filebug page for Firefox
-        client, start_url = self.getClientFor(
-            '/firefox/+filebug', user=lpuser.SAMPLE_PERSON)
-
-        # Ensure the "search" field has finished loading, then enter a simple
-        # search and hit search.
-        client.waits.forElement(
-            xpath=u'//input[@id="field.search"]',
-            timeout=constants.FOR_ELEMENT)
-        client.type(text=u'problem', id=u'field.search')
-        client.click(xpath=u'//input[@id="field.actions.search"]')
-
-        # The details div for the duplicate bug should not be shown.
-        client.waits.forElementProperty(
-            id='details-for-bug-4', option=BUG_INFO_HIDDEN,
-            timeout=constants.FOR_ELEMENT)
-
-        # The expander for the duplicate should be collapsed.
-        client.asserts.assertProperty(
-            id='bug-details-expander-bug-4',
-            validator='src|/@@/treeCollapsed')
-
-        # Initially the form overlay is hidden
-        client.asserts.assertElemJS(xpath=FORM_OVERLAY, js=FORM_NOT_VISIBLE)
-
-        # Clicking on the expander will expand it and show the details div.
-        client.click(id='bug-details-expander-bug-4')
-        client.waits.sleep(milliseconds=constants.SLEEP)
-        client.asserts.assertProperty(
-            id='bug-details-expander-bug-4', validator='src|/@@/treeExpanded')
-        client.asserts.assertElemJS(
-            id='details-for-bug-4', js=BUG_INFO_SHOWN_JS)
-
-        # Clicking the expander again will hide the details div and collapse
-        # the expander.
-        client.click(id='bug-details-expander-bug-4')
-        client.waits.sleep(milliseconds=constants.SLEEP)
-        client.asserts.assertProperty(
-            id='bug-details-expander-bug-4',
-            validator='src|/@@/treeCollapsed')
-        client.asserts.assertProperty(
-            id='details-for-bug-4', validator=BUG_INFO_HIDDEN)
-
-        # Clicking it yet again will reopen it.
-        client.click(id='bug-details-expander-bug-4')
-        client.waits.sleep(milliseconds=constants.SLEEP)
-        client.asserts.assertProperty(
-            id='bug-details-expander-bug-4', validator='src|/@@/treeExpanded')
-        client.asserts.assertElemJS(
-            id='details-for-bug-4', js=BUG_INFO_SHOWN_JS)
-
-        # Clicking on the "Yes, this is my bug button" will show a form
-        # overlay, which will offer the user the option to subscribe to the
-        # bug.
-        client.click(id="this-is-my-bug-4")
-        client.waits.sleep(milliseconds=constants.SLEEP)
-        client.asserts.assertElemJS(xpath=FORM_OVERLAY, js=FORM_VISIBLE)
-
-        # Clicking the cancel button will make the overlay go away again.
-        client.click(xpath=FORM_OVERLAY_CANCEL)
-        client.waits.sleep(milliseconds=constants.SLEEP)
-        client.asserts.assertElemJS(xpath=FORM_OVERLAY, js=FORM_NOT_VISIBLE)
-
-        # Validation errors are displayed on the current page.
-        client.click(id="bug-not-already-reported")
-        client.asserts.assertProperty(
-            id="filebug-form-container", validator="style.display|block",
-            timeout=constants.FOR_ELEMENT)
-        client.click(id="field.actions.submit_bug")
-        client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
-        client.asserts.assertText(
-            xpath=u'//div[@class="message"]',
-            validator="Provide details about the issue.")

=== modified file 'lib/lp/bugs/windmill/tests/test_official_bug_tags_management.py'
--- lib/lp/bugs/windmill/tests/test_official_bug_tags_management.py	2011-03-29 05:59:29 +0000
+++ lib/lp/bugs/windmill/tests/test_official_bug_tags_management.py	2011-06-27 15:56:40 +0000
@@ -15,6 +15,7 @@
 
 
 class TestOfficialBugTags(WindmillTestCase):
+    """XXX: Pull most to YUI test, but port XHR check at end."""
 
     layer = BugsWindmillLayer
     suite_name = 'Official bug tags management test'

=== removed file 'lib/lp/code/windmill/__init__.py'
=== removed file 'lib/lp/code/windmill/testing.py'
--- lib/lp/code/windmill/testing.py	2011-06-08 16:53:47 +0000
+++ lib/lp/code/windmill/testing.py	1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Code-specific testing infrastructure for Windmill."""
-
-__metaclass__ = type
-__all__ = [
-    'CodeWindmillLayer',
-    ]
-
-
-from canonical.testing.layers import BaseWindmillLayer
-
-
-class CodeWindmillLayer(BaseWindmillLayer):
-    """Layer for Code Windmill tests."""
-
-    @classmethod
-    def setUp(cls):
-        cls.facet = 'code'
-        cls.base_url = cls.appserver_root_url(cls.facet)
-        super(CodeWindmillLayer, cls).setUp()

=== removed file 'lib/lp/code/windmill/tests/__init__.py'
=== modified file 'lib/lp/code/windmill/tests/test_branch_popupdiff.py'
--- lib/lp/code/windmill/tests/test_branch_popupdiff.py	2011-03-29 05:59:29 +0000
+++ lib/lp/code/windmill/tests/test_branch_popupdiff.py	2011-06-27 15:56:40 +0000
@@ -42,6 +42,7 @@
     u'//ul[@class="yui3-picker-results"]//span[@class="yui3-picker-result-title"]')
 
 
+#XXX: Should be re-enabled for Selenium2.
 #class TestPopupOnBranchPage(WindmillTestCase):
 #    """Test the popup diff."""
 #

=== removed file 'lib/lp/code/windmill/tests/test_productseries_setbranch.py'
--- lib/lp/code/windmill/tests/test_productseries_setbranch.py	2011-03-29 05:59:29 +0000
+++ lib/lp/code/windmill/tests/test_productseries_setbranch.py	1970-01-01 00:00:00 +0000
@@ -1,51 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test for productseries setbranch Javascript."""
-
-__metaclass__ = type
-__all__ = []
-
-from lp.code.windmill.testing import CodeWindmillLayer
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import lpuser
-from lp.testing.windmill.constants import FOR_ELEMENT
-
-
-class TestProductSeriesSetbranch(WindmillTestCase):
-    """Test productseries +setbranch Javascript controls."""
-
-    layer = CodeWindmillLayer
-    suite_name = 'ProductSeriesSetBranch'
-
-    def test_productseries_setbranch(self):
-        """Test productseries JS on /$projectseries/+setbranch page."""
-
-        # Ensure we're logged in as 'foo bar'
-        client, start_url = self.getClientFor(
-            '/firefox/trunk/+setbranch', user=lpuser.FOO_BAR)
-
-        # To demonstrate the Javascript is loaded we simply need to see that
-        # one of the controls is deactivated when the radio button selections
-        # change.  When "Link to a Bazaar branch" is selected the
-        # branch_location field should be enabled.  When any other radio
-        # button is selected the branch_location field is disabled.
-        self.client.waits.forElement(id=u'field.branch_type.link-lp-bzr',
-                                     timeout=FOR_ELEMENT)
-
-        # Select Bazaar as the RCS type...
-        self.client.click(id=u'field.branch_type.link-lp-bzr')
-        self.client.waits.forElement(id=u'field.branch_location',
-                                     timeout=FOR_ELEMENT)
-        # And the branch location is enabled.
-        self.client.asserts.assertElemJS(id=u'field.branch_location',
-                                         js='!element.disabled')
-
-        # Select 'create new'...
-        self.client.click(id=u'field.branch_type.create-new')
-        self.client.waits.forElement(id=u'field.branch_location',
-                                     timeout=FOR_ELEMENT)
-        # And the branch location is now disabled, proving that the javascript
-        # controls have loaded and are functioning.
-        self.client.asserts.assertElemJS(id=u'field.branch_location',
-                                         js='element.disabled')

=== modified file 'lib/lp/code/windmill/tests/test_recipe_index.py'
--- lib/lp/code/windmill/tests/test_recipe_index.py	2011-05-16 00:33:30 +0000
+++ lib/lp/code/windmill/tests/test_recipe_index.py	2011-06-27 15:56:40 +0000
@@ -46,6 +46,7 @@
         self.assertTrue(freshly_fetched_recipe.build_daily)
 
     def test_inline_recipe_text_errors(self):
+        # XXX: do we really want to error check here?
         eric = self.factory.makePerson(
             name="eric", displayname="Eric the Viking", password="test",
             email="eric@xxxxxxxxxxx")

=== removed file 'lib/lp/registry/windmill/__init__.py'
=== removed file 'lib/lp/registry/windmill/testing.py'
--- lib/lp/registry/windmill/testing.py	2011-06-08 16:53:47 +0000
+++ lib/lp/registry/windmill/testing.py	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Registry-specific testing infrastructure for Windmill."""
-
-__metaclass__ = type
-__all__ = [
-    'RegistryWindmillLayer',
-    ]
-
-
-from canonical.testing.layers import BaseWindmillLayer
-
-
-class RegistryWindmillLayer(BaseWindmillLayer):
-    """Layer for Registry Windmill tests."""
-
-    @classmethod
-    def setUp(cls):
-        cls.base_url = cls.appserver_root_url()
-        super(RegistryWindmillLayer, cls).setUp()

=== removed file 'lib/lp/registry/windmill/tests/__init__.py'
=== modified file 'lib/lp/registry/windmill/tests/test_add_bugtracker.py'
--- lib/lp/registry/windmill/tests/test_add_bugtracker.py	2011-03-29 05:59:29 +0000
+++ lib/lp/registry/windmill/tests/test_add_bugtracker.py	2011-06-27 15:56:40 +0000
@@ -47,6 +47,7 @@
         client.click(id=u'formoverlay-add-bugtracker')
 
         # Verify that the bugtracker name was entered in the text box.
+        # XXX: pushed down to YUI tests, if we care.
         client.waits.sleep(milliseconds='1000')
         client.asserts.assertProperty(
             id="field.bugtracker.bugtracker",
@@ -55,6 +56,7 @@
 
         # Verify error message when trying to create a bugtracker with a
         # conflicting name.
+        # XXX: no error checking in browser tests.
         client.click(id=u'create-bugtracker-link')
         client.waits.forElement(id=u'field.name')
         client.type(id='field.name', text=bugtracker_name)

=== modified file 'lib/lp/registry/windmill/tests/test_add_milestone.py'
--- lib/lp/registry/windmill/tests/test_add_milestone.py	2011-03-29 05:59:29 +0000
+++ lib/lp/registry/windmill/tests/test_add_milestone.py	2011-06-27 15:56:40 +0000
@@ -51,12 +51,14 @@
 
         # Verify that the milestone was added to the SELECT input,
         # and that it is now selected.
+        # XXX: push to YUI test, if we care.
         client.waits.sleep(milliseconds=SLEEP)
         client.asserts.assertSelected(id="field.milestone_for_release",
                                       validator=milestone_name.lower())
 
         # Verify error message when trying to create a milestone with a
         # conflicting name.
+        # XXX: don't check errors in browser
         client.click(id=u'create-milestone-link')
         client.waits.forElement(id=u'field.name', timeout=FOR_ELEMENT)
         client.type(id='field.name', text=milestone_name)

=== modified file 'lib/lp/registry/windmill/tests/test_datetime_picker.py'
--- lib/lp/registry/windmill/tests/test_datetime_picker.py	2011-03-29 05:59:29 +0000
+++ lib/lp/registry/windmill/tests/test_datetime_picker.py	2011-06-27 15:56:40 +0000
@@ -13,7 +13,11 @@
 
 
 class TestDateTimeCalendarWidget(WindmillTestCase):
-    """Test datetime calendar widget."""
+    """Test datetime calendar widget.
+
+    XXX: This entire test should move to YUI test.
+    It asserts widget state, but has no XHR component.
+    """
 
     layer = RegistryWindmillLayer
     suite_name = 'DateTimeCalendarWidget'

=== modified file 'lib/lp/registry/windmill/tests/test_person_picker.py'
--- lib/lp/registry/windmill/tests/test_person_picker.py	2011-05-28 10:58:34 +0000
+++ lib/lp/registry/windmill/tests/test_person_picker.py	2011-06-27 15:56:40 +0000
@@ -25,6 +25,7 @@
     suite_name = 'PersonPickerWidget'
 
     def test_person_picker_widget(self):
+        """XXX: this should all move to test_picker.js"""
 
         client, start_url = self.getClientFor(
             '/people/+requestmerge', user=lpuser.SAMPLE_PERSON)

=== modified file 'lib/lp/registry/windmill/tests/test_plusnew_step1.py'
--- lib/lp/registry/windmill/tests/test_plusnew_step1.py	2011-03-30 05:18:07 +0000
+++ lib/lp/registry/windmill/tests/test_plusnew_step1.py	2011-06-27 15:56:40 +0000
@@ -25,6 +25,7 @@
 
         On step 1 of the wizard, the URL field gets autofilled from the Name
         field.  Also, the URL field will not accept invalid characters.
+        XXX: Move entire test to YUI test.
         """
         # Perform step 1 of the project registration, using information
         # that will yield search results.

=== removed file 'lib/lp/registry/windmill/tests/test_plusnew_step2.py'
--- lib/lp/registry/windmill/tests/test_plusnew_step2.py	2011-04-04 23:58:57 +0000
+++ lib/lp/registry/windmill/tests/test_plusnew_step2.py	1970-01-01 00:00:00 +0000
@@ -1,86 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test for form for creating a project."""
-
-__metaclass__ = type
-__all__ = []
-
-from lp.registry.windmill.testing import RegistryWindmillLayer
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import lpuser
-from lp.testing.windmill.constants import FOR_ELEMENT
-
-class TestNewProjectStep2(WindmillTestCase):
-    """Test form for creating a new project."""
-
-    layer = RegistryWindmillLayer
-    suite_name = 'TestNewProjectStep2'
-
-    def test_projects_plusnew_step_two(self):
-        """Test the dynamic aspects of step 2 of projects/+new page.
-
-        When the project being registered matches existing projects, the
-        step two page has some extra javascript-y goodness.  At the
-        start, there's a 'No' button that hides the search results and
-        reveals the rest of the project registration form.  After that,
-        there's a href that toggles between revealing the search results
-        and hiding them.
-        """
-
-        # Perform step 1 of the project registration, using information
-        # that will yield search results.
-        client, start_url = self.getClientFor(
-            '/projects/+new', user=lpuser.SAMPLE_PERSON)
-        self.client.waits.forElement(
-            id='field.displayname', timeout=FOR_ELEMENT)
-
-        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')
-        self.client.type(text=u'Badgers ate my firefox', id='field.summary')
-        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.assertTextIn(
-            id=u'step-title',
-            validator=u'Check for duplicate projects')
-
-        # Clicking on the "No" button hides the button and search
-        # results, reveals the form widgets, and reveals an href link
-        # 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.assertTextIn(
-            id=u'step-title',
-            validator=u'Registration details')
-
-        # The className for hidden elements is lazr-closed  because it's
-        # set by the slide-in effect.  For slide-out elements, it's
-        # lazr-opened.
-        self.client.asserts.assertProperty(
-            id='search-results', validator='className|lazr-closed')
-        self.client.asserts.assertProperty(
-            id=u'launchpad-form-widgets',
-            validator='className|lazr-opened')
-        self.client.asserts.assertNotProperty(
-            id=u'search-results-expander',
-            validator='className|unseen')
-        # Clicking on the href expands the search results.
-        self.client.click(id='search-results-expander')
-        self.client.waits.forElement(
-            xpath='//*[@id="search-results" '
-                  'and contains(@class, "lazr-opened")]',
-            milliseconds=u'1000')
-        self.client.asserts.assertProperty(
-            id=u'search-results',
-            validator='className|lazr-opened')
-        # Clicking it again hides the results.
-        self.client.click(id='search-results-expander')
-        self.client.waits.forElement(
-            xpath='//*[@id="search-results" '
-                  'and contains(@class, "lazr-closed")]',
-            milliseconds=u'1000')
-        self.client.asserts.assertProperty(
-            id=u'search-results',
-            validator='className|lazr-closed')

=== removed file 'lib/lp/registry/windmill/tests/test_product.py'
--- lib/lp/registry/windmill/tests/test_product.py	2011-03-29 07:10:40 +0000
+++ lib/lp/registry/windmill/tests/test_product.py	1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test product index page."""
-
-__metaclass__ = type
-__all__ = []
-
-from lp.registry.windmill.testing import RegistryWindmillLayer
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import (
-    lpuser,
-    widgets,
-    )
-
-
-class TestProductIndexPage(WindmillTestCase):
-    """Test product index page."""
-
-    layer = RegistryWindmillLayer
-
-    def test_title_inline_edit(self):
-        test = widgets.InlineEditorWidgetTest(
-            url='%s/firefox' % RegistryWindmillLayer.base_url,
-            widget_id='edit-title',
-            expected_value='Mozilla Firefox',
-            new_value='The awesome Mozilla Firefox',
-            name='test_title_inline_edit',
-            suite_name=__name__,
-            user=lpuser.SAMPLE_PERSON)
-        test()
-
-    def test_programming_languages_edit(self):
-        test = widgets.InlineEditorWidgetTest(
-            url='%s/firefox' % RegistryWindmillLayer.base_url,
-            widget_id='edit-programminglang',
-            widget_tag='span',
-            expected_value='Not yet specified',
-            new_value='C++',
-            name='test_proglang_inline_edit',
-            suite_name=__name__,
-            user=lpuser.SAMPLE_PERSON)
-        test()

=== removed file 'lib/lp/registry/windmill/tests/test_product_configuration_hidden.py'
--- lib/lp/registry/windmill/tests/test_product_configuration_hidden.py	2011-03-29 05:59:29 +0000
+++ lib/lp/registry/windmill/tests/test_product_configuration_hidden.py	1970-01-01 00:00:00 +0000
@@ -1,82 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-import transaction
-
-from lp.registry.windmill.testing import RegistryWindmillLayer
-from lp.testing import WindmillTestCase
-from lp.testing.service_usage_helpers import set_service_usage
-from lp.testing.windmill import (
-    constants,
-    lpuser,
-    )
-
-
-class TestProductHiddenConfiguration(WindmillTestCase):
-    """Test the Configuration links show/hide controls on products.
-
-    Controls only work with javascript enabled.
-    """
-
-    layer = RegistryWindmillLayer
-    suite_name = "Product configuration links hidden"
-
-    def setUp(self):
-        super(TestProductHiddenConfiguration, self).setUp()
-        self.product = self.factory.makeProduct(name='hidden-configs')
-        transaction.commit()
-
-    def test_not_fully_configured_starts_shown(self):
-        # A product that is not fully configured displays the links on
-        # page load, but they can be hidden.
-
-        client, start_url = self.getClientFor(
-            '/hidden-configs', user=lpuser.FOO_BAR,
-            base_url=self.layer.appserver_root_url())
-
-        # We can only safely use this class selector in this test b/c there's
-        # only one collapsible element on this page.
-        client.asserts.assertNotProperty(
-            classname='collapseWrapper',
-            validator='className|lazr-closed')
-
-        # When the "Configuration links" link is clicked and the actual links are
-        # shown, the collapsible wrapper collapses, hiding the links.
-        client.click(link=u"Configuration options")
-        client.waits.forElement(
-            classname="collapseWrapper lazr-closed",
-            timeout=constants.FOR_ELEMENT)
-        client.asserts.assertProperty(
-            classname='collapseWrapper',
-            validator='className|lazr-closed')
-
-    def test_configured_starts_collapsed(self):
-        # A product that is fully configured hides the links on page
-        # load, but they can be hidden.
-        set_service_usage(
-            self.product.name,
-            codehosting_usage="EXTERNAL",
-            bug_tracking_usage="LAUNCHPAD",
-            answers_usage="EXTERNAL",
-            translations_usage="NOT_APPLICABLE")
-        transaction.commit()
-
-        client, start_url = self.getClientFor(
-            '/hidden-configs', user=lpuser.FOO_BAR,
-            base_url=self.layer.appserver_root_url())
-        client.waits.forElement(
-            classname='collapseWrapper lazr-closed',
-            timeout=constants.FOR_ELEMENT)
-        client.asserts.assertProperty(
-            classname='collapseWrapper',
-            validator='className|lazr-closed')
-
-        # When the "Configuration links" link is clicked and the actual links are
-        # hidden, the collapsible wrapper opens, showing the links.
-        client.click(link=u"Configuration options")
-        client.waits.forElement(
-            classname="lazr-opened",
-            timeout=constants.FOR_ELEMENT)
-        client.asserts.assertProperty(
-            classname='collapseWrapper',
-            validator='className|lazr-open')

=== removed file 'lib/lp/registry/windmill/tests/test_product_edit_people.py'
--- lib/lp/registry/windmill/tests/test_product_edit_people.py	2011-03-29 07:10:40 +0000
+++ lib/lp/registry/windmill/tests/test_product_edit_people.py	1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test picker on +edit-people page."""
-
-__metaclass__ = type
-__all__ = []
-
-
-from lp.registry.windmill.testing import RegistryWindmillLayer
-from lp.testing import WindmillTestCase
-from lp.testing.windmill.widgets import FormPickerWidgetTest
-
-
-class TestProductEditPeople(WindmillTestCase):
-    """Test picker +edit-people page."""
-
-    layer = RegistryWindmillLayer
-
-    def test_product_edit_people_driver(self):
-        test = FormPickerWidgetTest(
-            name='test_product_edit_people_driver',
-            url='%s/firefox/+edit-people' % RegistryWindmillLayer.base_url,
-            short_field_name='driver',
-            search_text='Perell\xc3\xb3',
-            result_index=1,
-            new_value='carlos')
-        test()
-
-    def test_product_edit_people_owner(self):
-        test = FormPickerWidgetTest(
-            name='test_product_edit_people_owner',
-            url='%s/firefox/+edit-people' % RegistryWindmillLayer.base_url,
-            short_field_name='owner',
-            search_text='guadamen',
-            result_index=1,
-            new_value='guadamen')
-        test()

=== modified file 'lib/lp/registry/windmill/tests/test_project_licenses.py'
--- lib/lp/registry/windmill/tests/test_project_licenses.py	2011-03-29 05:59:29 +0000
+++ lib/lp/registry/windmill/tests/test_project_licenses.py	2011-06-27 15:56:40 +0000
@@ -13,7 +13,10 @@
 
 
 class TestProjectLicenses(WindmillTestCase):
-    """Test project licenses picker."""
+    """Test project licenses picker.
+
+    XXX: This needs to be YUI test.
+    """
 
     layer = RegistryWindmillLayer
     suite_name = 'TestProjectLicenses'

=== removed file 'lib/lp/registry/windmill/tests/test_timeline_graph.py'
--- lib/lp/registry/windmill/tests/test_timeline_graph.py	2010-10-18 12:56:47 +0000
+++ lib/lp/registry/windmill/tests/test_timeline_graph.py	1970-01-01 00:00:00 +0000
@@ -1,82 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test for timeline graph widget."""
-
-__metaclass__ = type
-__all__ = []
-
-import unittest
-
-from lp.registry.windmill.testing import RegistryWindmillLayer
-from lp.testing import WindmillTestCase
-
-
-class TestTimelineGraph(WindmillTestCase):
-    """Test timeline graph widget."""
-
-    layer = RegistryWindmillLayer
-    suite_name = 'TimelineGraph'
-
-    def test_timeline_graph(self):
-        """Test timeline graph on /$project/+timeline-graph page."""
-
-        self.client.open(
-            url=u'%s/firefox/+timeline-graph'
-                % RegistryWindmillLayer.base_url)
-        self.client.waits.forElement(id=u'spinner', timeout=u'20000')
-        self.client.waits.forElementProperty(
-            id=u'spinner',
-            option=u'style.display|none',
-            timeout=u'8000')
-        link_xpath = '//div/a[@href="/firefox/trunk"]'
-
-        self.client.waits.forElement(xpath=link_xpath)
-
-    def test_project_timeline_graph(self):
-        """Test that the timeline graph loads on /$project page."""
-
-        self.client.open(url=u'%s/firefox' % RegistryWindmillLayer.base_url)
-
-        self.client.waits.forElementProperty(
-            id=u'timeline-loading',
-            option=u'style.display|none',
-            timeout=u'20000')
-        self.client.waits.forElementProperty(
-            id=u'timeline-iframe',
-            option=u'style.display|block',
-            timeout=u'8000')
-
-    def test_series_timeline_graph(self):
-        """Test that the timeline graph loads on /$project/$series page."""
-
-        self.client.open(url=u'%s/firefox/trunk'
-                        % RegistryWindmillLayer.base_url)
-
-        self.client.waits.forElementProperty(
-            id=u'timeline-iframe',
-            option=u'style.display|block',
-            timeout=u'8000')
-        self.client.waits.forElement(id=u'timeline-loading', timeout=u'20000')
-
-        self.client.waits.forElementProperty(
-            id=u'timeline-loading',
-            option=u'style.display|none')
-
-    def test_all_series_timeline_graph(self):
-        """Test that the timeline graph loads on /$project/+series page."""
-
-        self.client.open(url=u'%s/firefox/+series'
-                        % RegistryWindmillLayer.base_url)
-
-        self.client.waits.forElement(
-            id=u'timeline-loading',
-            option=u'style.display|none',
-            timeout=u'20000')
-        self.client.waits.forElementProperty(
-            id=u'timeline-iframe',
-            option=u'style.display|block',
-            timeout=u'8000')
-
-def test_suite():
-    return unittest.TestLoader().loadTestsFromName(__name__)

=== removed file 'lib/lp/soyuz/windmill/__init__.py'
=== removed file 'lib/lp/soyuz/windmill/testing.py'
--- lib/lp/soyuz/windmill/testing.py	2011-06-08 16:53:47 +0000
+++ lib/lp/soyuz/windmill/testing.py	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Soyuz-specific testing infrastructure for Windmill."""
-
-__metaclass__ = type
-__all__ = [
-    'SoyuzWindmillLayer',
-    ]
-
-
-from canonical.testing.layers import BaseWindmillLayer
-
-
-class SoyuzWindmillLayer(BaseWindmillLayer):
-    """Layer for Soyuz Windmill tests."""
-
-    @classmethod
-    def setUp(cls):
-        cls.base_url = cls.appserver_root_url()
-        super(SoyuzWindmillLayer, cls).setUp()

=== removed file 'lib/lp/soyuz/windmill/tests/__init__.py'
=== removed file 'lib/lp/soyuz/windmill/tests/test_ppainlineedit.py'
--- lib/lp/soyuz/windmill/tests/test_ppainlineedit.py	2011-03-29 07:10:40 +0000
+++ lib/lp/soyuz/windmill/tests/test_ppainlineedit.py	1970-01-01 00:00:00 +0000
@@ -1,30 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-import unittest
-
-from lp.soyuz.windmill.testing import SoyuzWindmillLayer
-from lp.testing.windmill import (
-    lpuser,
-    widgets,
-    )
-
-
-class TestPPAInlineEditing(unittest.TestCase):
-    """Ensure that various inline editing on the PPA page work."""
-
-    layer = SoyuzWindmillLayer
-
-    def test_ppa_displayname_inline_edit(self):
-        """Ensure the PPA dispalyname can be edited inline."""
-
-        ppa_displayname_inline_edit_test = widgets.InlineEditorWidgetTest(
-            url='%s/~cprov/+archive/ppa' % SoyuzWindmillLayer.base_url,
-            widget_id='edit-displayname',
-            expected_value='PPA for Celso Providelo',
-            new_value="Celso's default PPA",
-            name='test_ppa_displayname_inline_edit',
-            user=lpuser.FOO_BAR,
-            suite_name=__name__)
-
-        ppa_displayname_inline_edit_test()

=== modified file 'lib/lp/testing/__init__.py'
--- lib/lp/testing/__init__.py	2011-06-24 22:40:32 +0000
+++ lib/lp/testing/__init__.py	2011-06-27 15:56:40 +0000
@@ -4,7 +4,6 @@
 # pylint: disable-msg=W0401,C0301,F0401
 
 from __future__ import absolute_import
-from lp.testing.windmill.lpuser import LaunchpadUser
 
 
 __metaclass__ = type
@@ -43,7 +42,6 @@
     'time_counter',
     'unlink_source_packages',
     'validate_mock_class',
-    'WindmillTestCase',
     'with_anonymous_login',
     'with_celebrity_logged_in',
     'with_person_logged_in',
@@ -98,7 +96,6 @@
 from testtools.matchers import MatchesRegex
 from testtools.testcase import ExpectedException as TTExpectedException
 import transaction
-from windmill.authoring import WindmillTestClient
 from zope.component import (
     adapter,
     getUtility,
@@ -165,10 +162,6 @@
     )
 from lp.testing.fixture import ZopeEventHandlerFixture
 from lp.testing.karma import KarmaRecorder
-from lp.testing.windmill import (
-    constants,
-    lpuser,
-    )
 
 # The following names have been imported for the purpose of being
 # exported. They are referred to here to silence lint warnings.
@@ -805,73 +798,6 @@
             self.getMainContent(context, view_name, rootsite, no_login, user))
 
 
-class WindmillTestCase(TestCaseWithFactory):
-    """A TestCase class for Windmill tests.
-
-    It provides a WindmillTestClient (self.client) with Launchpad's front
-    page loaded.
-    """
-
-    suite_name = ''
-
-    def setUp(self):
-        super(WindmillTestCase, self).setUp()
-        self.client = WindmillTestClient(self.suite_name)
-        # Load the front page to make sure we don't get fooled by stale pages
-        # left by the previous test. (For some reason, when you create a new
-        # WindmillTestClient you get a new session and everything, but if you
-        # do anything before you open() something you'd be operating on the
-        # page that was last accessed by the previous test, which is the cause
-        # of things like https://launchpad.net/bugs/515494)
-        self.client.open(url=self.layer.appserver_root_url())
-
-    def getClientFor(self, obj, user=None, password='test', base_url=None,
-                     view_name=None):
-        """Return a new client, and the url that it has loaded."""
-        client = WindmillTestClient(self.suite_name)
-        if user is not None:
-            if isinstance(user, LaunchpadUser):
-                email = user.email
-                password = user.password
-            else:
-                email = removeSecurityProxy(user).preferredemail.email
-            client.open(url=lpuser.get_basic_login_url(email, password))
-            client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
-        if isinstance(obj, basestring):
-            url = obj
-        else:
-            url = canonical_url(
-                obj, view_name=view_name, rootsite=self.layer.facet,
-                force_local_path=True)
-        if base_url is None:
-            base_url = self.layer.base_url
-        obj_url = base_url + url
-        client.open(url=obj_url)
-        client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
-        return client, obj_url
-
-    def getClientForPerson(self, url, person, password='test'):
-        """Create a LaunchpadUser for a person and login to the url."""
-        naked_person = removeSecurityProxy(person)
-        user = LaunchpadUser(
-            person.displayname, naked_person.preferredemail.email, password)
-        return self.getClientFor(url, user=user)
-
-    def getClientForAnonymous(self, obj, view_name=None):
-        """Return a new client, and the url that it has loaded."""
-        client = WindmillTestClient(self.suite_name)
-        if isinstance(obj, basestring):
-            url = obj
-        else:
-            url = canonical_url(
-                obj, view_name=view_name, force_local_path=True)
-        obj_url = self.layer.base_url + url
-        obj_url = obj_url.replace('http://', 'http://foo:foo@')
-        client.open(url=obj_url)
-        client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
-        return client, obj_url
-
-
 class WebServiceTestCase(TestCaseWithFactory):
     """Test case optimized for testing the web service using launchpadlib."""
 

=== removed directory 'lib/lp/testing/windmill'
=== removed file 'lib/lp/testing/windmill/__init__.py'
=== removed file 'lib/lp/testing/windmill/constants.py'
--- lib/lp/testing/windmill/constants.py	2009-10-27 12:34:17 +0000
+++ lib/lp/testing/windmill/constants.py	1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# -*- encoding: utf-8 -*-
-
-"""Constants for use in Windmill tests written in Python."""
-
-__metaclass__ = type
-__all__ = []
-
-PAGE_LOAD = unicode(40000)
-FOR_ELEMENT = unicode(20000)
-SLEEP = unicode(5000)
-

=== removed file 'lib/lp/testing/windmill/lpuser.py'
--- lib/lp/testing/windmill/lpuser.py	2011-03-29 05:59:29 +0000
+++ lib/lp/testing/windmill/lpuser.py	1970-01-01 00:00:00 +0000
@@ -1,40 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Utilities for Windmill tests written in Python."""
-
-__metaclass__ = type
-__all__ = []
-
-import windmill
-
-
-def get_basic_login_url(email, password):
-    """Return the constructed url to login a user."""
-    base_url = windmill.settings['TEST_URL']
-    basic_auth_url = base_url.replace('http://', 'http://%s:%s@')
-    basic_auth_url = basic_auth_url + '+basiclogin'
-    return basic_auth_url % (email, password)
-
-
-class LaunchpadUser:
-    """Object representing well-known user on Launchpad."""
-
-    def __init__(self, display_name, email, password):
-        self.display_name = display_name
-        self.email = email
-        self.password = password
-
-
-# Well Known Users
-SAMPLE_PERSON = LaunchpadUser(
-    'Sample Person', 'test@xxxxxxxxxxxxx', 'test')
-
-FOO_BAR = LaunchpadUser(
-    'Foo Bar', 'foo.bar@xxxxxxxxxxxxx', 'test')
-
-NO_PRIV = LaunchpadUser(
-    'No Privileges User', 'no-priv@xxxxxxxxxxxxx', 'test')
-
-TRANSLATIONS_ADMIN = LaunchpadUser(
-    u'Carlos Perell\xf3 Mar\xedn', 'carlos@xxxxxxxxxxxxx', 'test')

=== removed file 'lib/lp/testing/windmill/widgets.py'
--- lib/lp/testing/windmill/widgets.py	2011-04-06 19:30:38 +0000
+++ lib/lp/testing/windmill/widgets.py	1970-01-01 00:00:00 +0000
@@ -1,391 +0,0 @@
-# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test helpers for common AJAX widgets."""
-
-__metaclass__ = type
-__all__ = [
-    'FormPickerWidgetTest',
-    'InlineEditorWidgetTest',
-    'InlinePickerWidgetButtonTest',
-    'InlinePickerWidgetSearchTest',
-    'OnPageWidget',
-    'search_and_select_picker_widget',
-    'search_picker_widget',
-    ]
-
-
-from windmill.authoring import WindmillTestClient
-
-from lp.testing.windmill import (
-    constants,
-    lpuser,
-    )
-
-
-class OnPageWidget:
-    """A class that represents and interacts with an on-page JavaScript widget.
-
-    The widget is assumed to be a YUI widget controlled by yui-X-hidden classes.
-    """
-
-    def __init__(self, client, widget_name):
-        """Constructor.
-
-        :param client: A WindmillTestClient instance for interacting with pages.
-        :param widget_name: The class name of the YUI widget, like 'yui3-picker'.
-        """
-        self.client = client
-        self.widget_name = widget_name
-
-    @property
-    def xpath(self):
-        """The XPath of this widget, not including the hidden or visible state.
-        """
-        # We include a space after the widget name because @class matches the
-        # /beginning/ of text strings, not whole words!
-        return u"//div[contains(@class, '%s ')]" % self.widget_name
-
-    @property
-    def visible_xpath(self):
-        """The XPath of the widget when it is visible on page."""
-        subs = dict(name=self.widget_name)
-        # We include a space after the widget name because @class matches the
-        # /beginning/ of text strings, not whole words!
-        return (u"//div[contains(@class, '%(name)s ') "
-                "and not(contains(@class, '%(name)s-hidden'))]" % subs)
-
-    @property
-    def hidden_xpath(self):
-        """The XPath of the widget when it is hidden."""
-        # We include a space after the widget name because @class matches the
-        # /beginning/ of text strings, not whole words!
-        subs = dict(name=self.widget_name)
-        return (u"//div[contains(@class, '%(name)s ') "
-                "and contains(@class, '%(name)s-hidden')]" % subs)
-
-    def should_be_visible(self):
-        """Check to see if the widget is visible on screen."""
-        self.client.waits.forElement(xpath=self.visible_xpath,
-                                     timeout=constants.FOR_ELEMENT)
-
-    def should_be_hidden(self):
-        """Check to see if the widget is hidden on screen."""
-        self.client.waits.forElement(xpath=self.hidden_xpath,
-                                     timeout=constants.FOR_ELEMENT)
-
-
-class SearchPickerWidget(OnPageWidget):
-    """A proxy for the yui3-picker widget from lazr-js."""
-
-    def __init__(self, client):
-        """Constructor.
-
-        :param client: A WindmillTestClient instance.
-        """
-        super(SearchPickerWidget, self).__init__(client, 'yui3-picker')
-        self.search_input_xpath = (
-            self.visible_xpath + "//input[@class='yui3-picker-search']")
-        self.search_button_xpath = (
-            self.visible_xpath +
-            "//div[@class='yui3-picker-search-box']/button")
-
-    def _get_result_xpath_by_number(self, item_number):
-        """Return the XPath for the given search result number."""
-        item_xpath = "//ul[@class='yui3-picker-results']/li[%d]/span" % item_number
-        return self.visible_xpath + item_xpath
-
-    def do_search(self, text):
-        """Enter some text in the search field and click the search button.
-
-        :param text: The text we want to search for.
-        """
-        self.client.waits.forElement(xpath=self.search_input_xpath,
-                                timeout=constants.FOR_ELEMENT)
-        self.client.type(xpath=self.search_input_xpath, text=text)
-        self.client.click(xpath=self.search_button_xpath,
-                          timeout=constants.FOR_ELEMENT)
-
-    def click_result_by_number(self, item_number):
-        """Click on the given result number in the results list.
-
-        :param item_number: The item in the results list we should click on.
-        """
-        item_xpath = self._get_result_xpath_by_number(item_number)
-        self.client.waits.forElement(xpath=item_xpath,
-                                     timeout=constants.FOR_ELEMENT)
-        self.client.click(xpath=item_xpath)
-
-
-class WidgetTest:
-    """A base class to provide logon capability."""
-    def getLoggedInClient(self):
-        """Return a new client, and the url that it has loaded."""
-        client = WindmillTestClient(self.suite_name)
-        email = self.user.email
-        password = self.user.password
-        client.open(url=lpuser.get_basic_login_url(email, password))
-        client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
-        client.open(url=self.url)
-        client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
-        return client
-
-
-class InlineEditorWidgetTest(WidgetTest):
-    """Test that the inline editor widget is working properly on a page."""
-
-    def __init__(self, url, widget_id, expected_value, new_value, name=None,
-                 suite_name='inline_editor', user=lpuser.NO_PRIV,
-                 widget_tag='h1'):
-        """Create a new InlineEditorWidgetTest.
-
-        :param url: The URL to the page on which the widget lives.
-        :param widget_id: The HTML id of the widget.
-        :param expected_value: The current expected value of the widget.
-        :param new_value: The value to change the field to.
-        :param suite: The suite in which this test is part of.
-        :param user: The user who should be logged in.
-        :param widget_tag: Element tag the widget is inside of.
-        """
-        self.url = url
-        if name is None:
-            self.__name__ = ('test_%s_inline_edit'
-                             % widget_id.replace('-', '_'))
-        else:
-            self.__name__ = name
-        self.widget_id = widget_id
-        self.expected_value = expected_value
-        self.new_value = new_value
-        self.suite_name = suite_name
-        self.user = user
-        self.widget_tag = widget_tag
-
-    def __call__(self):
-        """Tests the widget is hooked and works properly.
-
-        The test:
-        * opens the url;
-        * asserts that the widget is initialized to the expected value;
-        * uses the inline editor to change to the new value;
-        * asserts that the page was updated with the new value;
-        * reloads and verifies that the new value sticked.
-        """
-        client = self.getLoggedInClient()
-        widget_base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id)
-        client.waits.forElement(
-            xpath=widget_base + '/a', timeout=constants.FOR_ELEMENT)
-        client.asserts.assertText(
-            xpath=widget_base + '/span[1]', validator=self.expected_value)
-        client.click(xpath=widget_base + '/a')
-        client.waits.forElement(
-            xpath=widget_base + '/a', timeout=constants.FOR_ELEMENT)
-        client.waits.forElement(
-            xpath=widget_base + '//textarea', timeout=constants.FOR_ELEMENT)
-        client.type(
-            xpath=widget_base + '//textarea', text=self.new_value)
-        client.click(xpath=widget_base + '//button[last()]')
-        client.waits.forElement(
-            xpath=widget_base + '/span[1][text()="' + self.new_value + '"]',
-            timeout=constants.FOR_ELEMENT)
-
-
-def search_picker_widget(client, search_text):
-    """Search using an on-page picker widget."""
-    picker = SearchPickerWidget(client)
-    picker.should_be_visible()
-    picker.do_search(search_text)
-
-
-def search_and_select_picker_widget(client, search_text, result_index):
-    """Search using an on-page picker widget and click a search result."""
-    picker = SearchPickerWidget(client)
-    picker.should_be_visible()
-    picker.do_search(search_text)
-    picker.click_result_by_number(result_index)
-
-
-class InlinePickerWidgetSearchTest(WidgetTest):
-    """Test that the Picker widget edits a value inline."""
-
-    def __init__(self, url, activator_id, search_text, result_index,
-                 new_value, name=None, suite_name='inline_picker_search_test',
-                 user=lpuser.FOO_BAR):
-        """Create a new InlinePickerSearchWidgetTest.
-
-        :param url: The URL to the page on which the widget lives.
-        :param activator_id: The HTML id of the activator widget.
-        :param search_text: Picker search value.
-        :param result_index: Item in picker result to select.
-        :param new_value: The value to change the field to.
-        :param name: Override the test name, if necessary.
-        :param suite: The suite in which this test is part of.
-        :param user: The user who should be logged in.
-        """
-        self.url = url
-        if name is None:
-            self.__name__ = 'test_%s_inline_picker' % (
-                activator_id.replace('-', '_'),)
-        else:
-            self.__name__ = name
-        self.activator_id = activator_id
-        self.search_text = search_text
-        self.result_index = result_index
-        self.new_value = new_value
-        self.suite_name = suite_name
-        self.user = user
-
-    def __call__(self):
-        # Load page.
-        client = self.getLoggedInClient()
-
-        # Click on edit button.
-        button_xpath = (
-            u"//span[@id='%s']"
-             "/button[not(contains(@class, 'yui3-activator-hidden'))]"
-             % self.activator_id)
-        client.waits.forElement(
-            xpath=button_xpath,
-            timeout=constants.FOR_ELEMENT)
-        client.click(xpath=button_xpath)
-
-        # Search picker.
-        search_and_select_picker_widget(
-            client, self.search_text, self.result_index)
-
-        # Verify update.
-        client.waits.sleep(milliseconds=u'2000')
-        client.asserts.assertText(
-            xpath=u"//span[@id='%s']//a" % self.activator_id,
-            validator=self.new_value)
-
-        # Reload the page to verify that the selected value is persisted.
-        client.open(url=self.url)
-        client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
-
-        # Verify update, again.
-        client.waits.forElement(
-            xpath=u"//span[@id='%s']//a" % self.activator_id,
-            timeout=constants.FOR_ELEMENT)
-        client.asserts.assertText(
-            xpath=u"//span[@id='%s']//a" % self.activator_id,
-            validator=self.new_value)
-
-
-class InlinePickerWidgetButtonTest(WidgetTest):
-    """Test custom buttons/links added to the Picker."""
-
-    def __init__(self, url, activator_id, button_class, new_value,
-                 name=None, suite_name='inline_picker_button_test',
-                 user=lpuser.FOO_BAR):
-        """Create a new InlinePickerWidgetButtonTest.
-
-        :param url: The URL to the page on which the widget lives.
-        :param activator_id: The HTML id of the activator widget.
-        :param button_class: The CSS class identifying the button.
-        :param new_value: The value to change the field to.
-        :param name: Override the test name, if necessary.
-        :param suite: The suite in which this test is part of.
-        :param user: The user who should be logged in.
-        """
-        self.url = url
-        self.activator_id = activator_id
-        self.button_class = button_class
-        self.new_value = new_value
-        self.suite_name = suite_name
-        self.user = user
-        if name is None:
-            self.__name__ = 'test_%s_inline_picker' % (
-                activator_id.replace('-', '_'),)
-        else:
-            self.__name__ = name
-
-    def __call__(self):
-        # Load page.
-        client = self.getLoggedInClient()
-
-        # Click on edit button.
-        button_xpath = (
-            u"//span[@id='%s']"
-             "/button[not(contains(@class, 'yui3-activator-hidden'))]"
-             % self.activator_id)
-        client.waits.forElement(xpath=button_xpath, timeout=u'25000')
-        client.click(xpath=button_xpath)
-
-        # Click on remove button.
-        remove_button_xpath = (
-            u"//div[contains(@class, 'yui3-picker ') "
-             "and not(contains(@class, 'yui3-picker-hidden'))]"
-             "//*[contains(@class, '%s')]" % self.button_class)
-        client.waits.forElement(xpath=remove_button_xpath, timeout=u'25000')
-        client.click(xpath=remove_button_xpath)
-        client.waits.sleep(milliseconds=u'2000')
-
-        # Verify removal.
-        client.asserts.assertText(
-            xpath=u"//span[@id='%s']/span[@class='yui3-activator-data-box']"
-                  % self.activator_id,
-            validator=self.new_value)
-
-        # Reload the page to verify that the selected value is persisted.
-        client.open(url=self.url)
-        client.waits.forPageLoad(timeout=u'25000')
-
-        # Verify removal, again.
-        client.waits.forElement(
-            xpath=u"//span[@id='%s']/span[@class='yui3-activator-data-box']"
-                  % self.activator_id,
-            timeout=u'25000')
-        client.asserts.assertText(
-            xpath=u"//span[@id='%s']/span[@class='yui3-activator-data-box']"
-                  % self.activator_id,
-            validator=self.new_value)
-
-
-class FormPickerWidgetTest(WidgetTest):
-    """Test that the Picker widget edits a form value properly."""
-
-    def __init__(self, url, short_field_name, search_text, result_index,
-                 new_value, name=None, suite_name='form_picker',
-                 user=lpuser.FOO_BAR):
-        """Create a new FormPickerWidgetTest.
-
-        :param url: The URL to the page on which the widget lives.
-        :param short_field_name: The name of the Zope attribute. For example,
-                                 'owner' which has the id 'field.owner'.
-        :param search_text: Picker search value.
-        :param result_index: Item in picker result to select.
-        :param new_value: The value to change the field to.
-        :param name: Override the test name, if necessary.
-        :param suite: The suite in which this test is part of.
-        :param user: The user who should be logged in.
-        """
-        self.url = url
-        if name is None:
-            self.__name__ = 'test_%s_form_picker' % (
-                short_field_name.replace('-', '_'),)
-        else:
-            self.__name__ = name
-        self.search_text = search_text
-        self.result_index = result_index
-        self.new_value = new_value
-        self.suite_name = suite_name
-        self.user = user
-        self.choose_link_id = 'show-widget-field-%s' % short_field_name
-        self.field_id = 'field.%s' % short_field_name
-
-    def __call__(self):
-        # Load page.
-        client = self.getLoggedInClient()
-
-        # 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.
-        search_and_select_picker_widget(
-            client, self.search_text, self.result_index)
-
-        # Verify value.
-        client.asserts.assertProperty(
-            id=self.field_id, validator=u"value|%s" % self.new_value)

=== removed file 'lib/lp/translations/windmill/__init__.py'
=== removed file 'lib/lp/translations/windmill/testing.py'
--- lib/lp/translations/windmill/testing.py	2011-06-08 16:53:47 +0000
+++ lib/lp/translations/windmill/testing.py	1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Translations-specific testing infrastructure for Windmill."""
-
-__metaclass__ = type
-__all__ = [
-    'TranslationsWindmillLayer',
-    ]
-
-
-from canonical.testing.layers import BaseWindmillLayer
-
-
-class TranslationsWindmillLayer(BaseWindmillLayer):
-    """Layer for Translations Windmill tests."""
-
-    @classmethod
-    def setUp(cls):
-        cls.facet = 'translations'
-        cls.base_url = cls.appserver_root_url(cls.facet)
-        super(TranslationsWindmillLayer, cls).setUp()

=== removed file 'lib/lp/translations/windmill/tests/__init__.py'
=== removed file 'lib/lp/translations/windmill/tests/disabled_test_productseries_templates.py'
--- lib/lp/translations/windmill/tests/disabled_test_productseries_templates.py	2011-03-29 05:59:29 +0000
+++ lib/lp/translations/windmill/tests/disabled_test_productseries_templates.py	1970-01-01 00:00:00 +0000
@@ -1,69 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test for ProductSeries templates listing behaviour."""
-
-__metaclass__ = type
-__all__ = []
-
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import lpuser
-from lp.testing.windmill.constants import FOR_ELEMENT
-
-from lp.translations.windmill.testing import TranslationsWindmillLayer
-
-
-class EnableActionLinksTest(WindmillTestCase):
-    """Test that action links are enabled on mouseover."""
-
-    layer = TranslationsWindmillLayer
-    suite_name = "Template links activation"
-
-    MAX_ROW = 2
-
-    def _xpath_action_links(self, row_index, active):
-        """Return the xpath to the action links div of the specified row."""
-        # xpath positions are 1-based
-        row_pos = row_index+1
-        if active:
-            inactive_class = u"not(contains(@class, 'inactive_links'))"
-        else:
-            inactive_class = u"contains(@class, 'inactive_links')"
-        return (u"//tr[contains(@class, 'template_row')][%d]"
-                u"/td[contains(@class, 'actions_column')]"
-                u"/div[%s]" % (row_pos, inactive_class))
-
-    #XXX: Bjorn Tillenius 2009-12-09 bug=494488
-    #     The test_template_listing_admin_links test has been disabled,
-    #     since we don't know why it fails in ec2 and buildbot (on
-    #     hardy), but not locally (on karmic).
-    def disabled_test_template_listing_admin_links(self):
-        """Tests that that action links are disabled and enabled.
-
-        The test:
-        * opens the templates listing for the Evolution:trunk ProductSeries;
-        * verifies that all action_links are disabled initially;
-        * repeats for all table rows:
-          * simulates moving the mouse cursor onto the table row;
-          * verifies that the action links of the row are activated;
-          * simulates moving the mouse cursor off the table row;
-          * verifies that the action links of the row are deactivated;
-        """
-        client, start_url = self.getClientFor(
-            '/evolution/trunk/+templates', lpuser.TRANSLATIONS_ADMIN)
-
-        client.waits.forElement(id=u'templates_table', timeout=FOR_ELEMENT)
-        # All links are inactive to start with.
-        for row_num in range(self.MAX_ROW):
-            client.waits.forElement(
-                xpath=self._xpath_action_links(row_num, active=False))
-
-        # Action links are activated when the mouse is over the row.
-        for row_num in range(self.MAX_ROW):
-            client.mouseOver(classname=('template_row,%d' % row_num))
-            client.asserts.assertNode(
-                xpath=self._xpath_action_links(row_num, active=True))
-
-            client.mouseOut(classname=('template_row,%d' % row_num))
-            client.asserts.assertNode(
-                xpath=self._xpath_action_links(row_num, active=False))

=== removed file 'lib/lp/translations/windmill/tests/test_documentation_links.py'
--- lib/lp/translations/windmill/tests/test_documentation_links.py	2011-03-29 05:59:29 +0000
+++ lib/lp/translations/windmill/tests/test_documentation_links.py	1970-01-01 00:00:00 +0000
@@ -1,100 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test for translation documentation links behaviour."""
-
-__metaclass__ = type
-__all__ = []
-
-from zope.security.proxy import removeSecurityProxy
-
-from lp.app.enums import ServiceUsage
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import lpuser
-from lp.testing.windmill.constants import (
-    FOR_ELEMENT,
-    PAGE_LOAD,
-    )
-from lp.translations.windmill.testing import TranslationsWindmillLayer
-
-
-class DocumentationLinksTest(WindmillTestCase):
-    """Test that the documentation links on translation pages work."""
-
-    layer = TranslationsWindmillLayer
-    suite_name = "Translation documentation links"
-
-    def createPOTemplateWithPOTMsgSets(self, productseries, name,
-                                       number_of_potmsgsets):
-        potemplate = self.factory.makePOTemplate(
-            productseries=productseries, name=name)
-        for sequence in range(number_of_potmsgsets):
-            self.factory.makePOTMsgSet(potemplate, sequence=sequence+1)
-        removeSecurityProxy(potemplate).messagecount = number_of_potmsgsets
-        return potemplate
-
-    def test_documentation_links(self):
-        """Tests that documentation links are shown/hidden properly.
-
-        The test:
-        * opens a Spanish translation page;
-        * tries hiding the notification box;
-        * makes sure it's hidden when you stay on the same translation;
-        * makes sure it's shown again when you go to a different translation.
-        """
-
-        # Create a translation group with documentation to use in the test.
-        group = self.factory.makeTranslationGroup(
-            name='testing-group', title='Testing group',
-            url=(u'https://help.launchpad.net/Translations/'
-                 u'LaunchpadTranslators'))
-
-        # Create a translatable project with a template containing 15
-        # messages (so we can go to multiple pages of each translation).
-        project = self.factory.makeProduct(
-            name='test-product',
-            displayname='Test Product',
-            translations_usage=ServiceUsage.LAUNCHPAD)
-        removeSecurityProxy(project).translationgroup = group
-
-        potemplate = self.createPOTemplateWithPOTMsgSets(
-            productseries=project.development_focus, name='template',
-            number_of_potmsgsets=15)
-        import transaction
-        transaction.commit()
-
-        # Go to Evolution translations page logged in as translations admin.
-        client, start_url = self.getClientFor(
-            '/test-product/trunk/+pots/template/es/',
-            user=lpuser.TRANSLATIONS_ADMIN)
-
-        # Make sure notification box is shown.
-        client.waits.forElement(classname=u'important-notice-container',
-                                timeout=FOR_ELEMENT)
-        # Click the hide button.
-        client.waits.forElement(classname=u'important-notice-cancel-button',
-                                timeout=FOR_ELEMENT)
-        client.click(classname=u'important-notice-cancel-button')
-        # Hiding entire container looks ugly, so only the ballon itself
-        # is hidden.
-        client.waits.forElementProperty(classname=u'important-notice-balloon',
-                                        option=u'style.display|none',
-                                        timeout=FOR_ELEMENT)
-
-        # Navigating to the next page of this translation doesn't show
-        # the notification box.
-        client.click(classname=u'next')
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.asserts.assertProperty(classname=u'important-notice-container',
-                                      validator=u'style.display|none')
-
-        # Look at Catalan translations page to make sure that the
-        # notification box is visible even though user dismissed Spanish
-        # translation notification.
-        client.open(
-            url=(u'%s/test-product/trunk/+pots/template/ca/'
-                 % TranslationsWindmillLayer.base_url))
-        client.waits.forPageLoad(timeout=PAGE_LOAD)
-        client.asserts.assertNotProperty(
-            classname=u'important-notice-container',
-            validator=u'style.display|none')

=== modified file 'lib/lp/translations/windmill/tests/test_import_queue.py'
--- lib/lp/translations/windmill/tests/test_import_queue.py	2011-03-29 05:59:29 +0000
+++ lib/lp/translations/windmill/tests/test_import_queue.py	2011-06-27 15:56:40 +0000
@@ -23,196 +23,6 @@
 from lp.translations.windmill.testing import TranslationsWindmillLayer
 
 
-class ImportQueueEntryTest(WindmillTestCase):
-    """Test that the entries in the import queue can switch types."""
-
-    layer = TranslationsWindmillLayer
-    suite_name = 'Translations import queue entry'
-
-    FIELDS = {
-        'POT': [
-            'field.potemplate',
-            'field.name',
-            'field.translation_domain',
-            ],
-        'PO': [
-            'field.potemplate',
-            'field.potemplate_name',
-            'field.language',
-            ],
-        }
-    SELECT_FIELDS = [
-        'field.potemplate',
-        'field.language',
-    ]
-
-    def _getHiddenTRXpath(self, field_id):
-        if field_id in self.SELECT_FIELDS:
-            input_tag = 'select'
-        else:
-            input_tag = 'input'
-        return (
-            u"//tr[contains(@class,'unseen')]"
-            u"//%s[@id='%s']" % (input_tag, field_id))
-
-    def _assertAllFieldsVisible(self, client, fields):
-        """Assert that all given fields are visible.
-
-        Fields are visible if they do not have the "unseen" class set.
-        """
-        for field_id in fields:
-            client.asserts.assertNotNode(
-                xpath=self._getHiddenTRXpath(field_id))
-
-    def _assertAllFieldsHidden(self, client, fields):
-        """Assert that all given fields are hidden.
-
-        Fields are hidden if they have the "unseen" class set.
-        """
-        for field_id in fields:
-            client.asserts.assertNode(
-                xpath=self._getHiddenTRXpath(field_id))
-
-    def test_import_queue_entry(self):
-        """Tests that import queue entry fields behave correctly."""
-
-        # Go to import queue page logged in as translations admin.
-        client, start_url = self.getClientFor(
-            '/+imports/1', user=lpuser.TRANSLATIONS_ADMIN)
-
-        po_only_fields = set(self.FIELDS['PO']) - set(self.FIELDS['POT'])
-        pot_only_fields = set(self.FIELDS['POT']) - set(self.FIELDS['PO'])
-
-        # When the page is first called the file_type is set to POT and
-        # only the relevant form fields are displayed. When the file type
-        # select box is changed to PO, other fields are shown hidden while
-        # the first ones are hidden. Finally, all fields are hidden if the
-        # file type is unspecified.
-        client.waits.forElement(id=u'field.file_type', timeout=FOR_ELEMENT)
-        client.asserts.assertSelected(id=u'field.file_type', validator=u'POT')
-        self._assertAllFieldsVisible(client, self.FIELDS['POT'])
-        self._assertAllFieldsHidden(client, po_only_fields)
-
-        client.select(id=u'field.file_type', val=u'PO')
-        self._assertAllFieldsVisible(client, self.FIELDS['PO'])
-        self._assertAllFieldsHidden(client, pot_only_fields)
-
-        client.select(id=u'field.file_type', val=u'UNSPEC')
-        self._assertAllFieldsHidden(client, self.FIELDS['POT'])
-        self._assertAllFieldsHidden(client, self.FIELDS['PO'])
-
-    def test_import_queue_entry_template_selection_new_path(self):
-        # For template uploads, the template dropdown controls the
-        # template name & translation domain fields.  This saves the
-        # trouble of finding the exact strings when approving an update
-        # with path changes.
-        # If the upload's path does not match any existing templates,
-        # the dropdown has no template pre-selected.
-
-        # A productseries has two templates.
-        template1 = self.factory.makePOTemplate(
-            path='1.pot', name='name1', translation_domain='domain1')
-        productseries = template1.productseries
-        template2 = self.factory.makePOTemplate(
-            path='2.pot', name='name2', translation_domain='domain2')
-
-        # A new template upload for that entry has a path that doesn't
-        # match either of the existing templates.
-        base_filename = self.factory.getUniqueString(prefix='x')
-        path = base_filename + '.pot'
-        entry = self.factory.makeTranslationImportQueueEntry(
-            path=path, productseries=productseries)
-        transaction.commit()
-
-        # The client reviews the upload.
-        client, start_url = self.getClientFor(
-            entry, user=lpuser.TRANSLATIONS_ADMIN)
-        client.waits.sleep(milliseconds=SLEEP)
-
-        # No template is preselected in the templates dropdown.
-        client.asserts.assertSelected(id=u'field.potemplate', validator=u'')
-
-        # The template name and translation domain are pre-set to a
-        # guess based on the base filename.
-        client.asserts.assertValue(
-            id=u'field.name', validator=base_filename)
-        client.asserts.assertValue(
-            id=u'field.translation_domain', validator=base_filename)
-
-        # The user edits the name and translation domain.
-        client.type(id=u'field.name', text='new-name')
-        client.type(id=u'field.translation_domain', text='new-domain')
-
-        # The user selects an existing template from the dropdown.  This
-        # updates the name and domain fields.
-        client.select(id=u'field.potemplate', option=u'name1')
-        client.asserts.assertValue(id=u'field.name', validator='name1')
-        client.asserts.assertValue(
-            id=u'field.translation_domain', validator='domain1')
-
-        # When the user returns the dropbox to its original state, the
-        # last-entered name and domain come back.
-        client.select(id=u'field.potemplate', option=u'')
-        client.asserts.assertValue(id=u'field.name', validator='new-name')
-        client.asserts.assertValue(
-            id=u'field.translation_domain', validator='new-domain')
-
-        # Changing the name and domain to those of an existing domain
-        # also updates the dropdown.
-        client.type(id=u'field.name', text=u'name1')
-        client.type(id=u'field.translation_domain', text=u'domain1')
-        client.asserts.assertSelected(
-            id=u'field.potemplate', validator=u'name1')
-
-    def test_import_queue_entry_template_selection_existing_path(self):
-        # If a template upload's base path matches the name/domain of an
-        # existing template, the templates dropdown has that template
-        # pre-selected.
-        template_name = self.factory.getUniqueString(prefix='x')
-        path = template_name + '.pot'
-        template = self.factory.makePOTemplate(
-            path=path, name=template_name, translation_domain=template_name)
-
-        # A new template upload for that entry has a path that doesn't
-        # match either of the existing templates.
-        entry = self.factory.makeTranslationImportQueueEntry(
-            path=path, productseries=template.productseries,
-            distroseries=template.distroseries,
-            sourcepackagename=template.sourcepackagename)
-        transaction.commit()
-
-        # The client reviews the upload.
-        client, start_url = self.getClientFor(
-            entry, user=lpuser.TRANSLATIONS_ADMIN)
-        client.waits.sleep(milliseconds=SLEEP)
-
-        # The matching template is preselected in the templates dropdown.
-        client.asserts.assertSelected(
-            id=u'field.potemplate', validator=template_name)
-
-    def test_import_queue_entry_template_selection_escape(self):
-        # The potemplate dropdown for templates escapes its strings.
-        template = self.factory.makePOTemplate(
-            path='quote.pot', name='quote', translation_domain="\\'")
-
-        # A new template upload for that entry has a path that doesn't
-        # match either of the existing templates.
-        entry = self.factory.makeTranslationImportQueueEntry(
-            path='foo.pot', productseries=template.productseries,
-            distroseries=template.distroseries,
-            sourcepackagename=template.sourcepackagename)
-        transaction.commit()
-
-        client, start_url = self.getClientFor(
-            entry, user=lpuser.TRANSLATIONS_ADMIN)
-        client.waits.sleep(milliseconds=SLEEP)
-
-        client.select(id=u'field.potemplate', option=u'quote')
-
-        client.asserts.assertValue(
-            id=u'field.translation_domain', validator=u"\\'")
-
-
 IMPORT_STATUS = u"//tr[@id='%d']//span[contains(@class,'status-choice')]"
 IMPORT_STATUS_1 = IMPORT_STATUS % 1
 OPEN_CHOICELIST = u"//div[contains(@class, 'yui3-ichoicelist-content')]"

=== removed file 'lib/lp/translations/windmill/tests/test_import_queue_error_output.py.disabled'
--- lib/lp/translations/windmill/tests/test_import_queue_error_output.py.disabled	2011-02-10 04:00:00 +0000
+++ lib/lp/translations/windmill/tests/test_import_queue_error_output.py.disabled	1970-01-01 00:00:00 +0000
@@ -1,66 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test interactive error output display in the import queue UI."""
-
-__metaclass__ = type
-__all__ = []
-
-# Generated by the windmill services transformer
-from windmill.authoring import WindmillTestClient
-
-from lp.translations.windmill.testing import TranslationsWindmillLayer
-from lp.testing import TestCaseWithFactory
-from lp.testing.windmill import lpuser
-
-
-class ImportQueueErrorOutputTest(TestCaseWithFactory):
-    """Test interactive error output display in the import queue UI."""
-
-    layer = TranslationsWindmillLayer
-
-    def _checkOutputPanel(self, client, panel_xpath):
-        client.waits.forElement(xpath=panel_xpath, timeout=u'5000')
-        # XXX JeroenVermeulen 2009-04-21 bug=365176: Check panel
-        # contents here!
-
-    def test_import_queue_error_output(self):
-        """Run test.
-
-        The test:
-        * produces an environment with failed translation imports;
-        * loads the translation import queue page;
-        * tests that the error output can be revealed interactively;
-        * tests that the error output can be hidden again.
-        """
-        client = WindmillTestClient("Translation imports error reporting")
-
-        start_url = 'http://translations.launchpad.dev:8085/+imports'
-        user = lpuser.TRANSLATIONS_ADMIN
-
-        client.open(url=start_url)
-        client.waits.forPageLoad(timeout=u'20000')
-        user.ensure_login(client)
-
-        placeholder = u"//div[@id='1']//div[@class='original show-output']"
-        client.waits.forElement(xpath=placeholder, timeout=u'8000')
-        client.click(xpath=placeholder)
-
-        show_button = u"//div[@id='1']//div[@class='new show-output']"
-        client.waits.forElement(xpath=show_button, timeout=u'8000')
-
-        output_panel = (
-            u"//div[@id='1']//tr[@class='discreet secondary output-panel]'")
-        self._checkOutputPanel(client, output_panel)
-
-        # Hide output panel.
-        client.click(xpath=show_button)
-        # XXX JeroenVermeulen 2009-04-21 bug=365176: waits.forElement() to
-        # wait for the output panel to disappear.
-        client.asserts.assertNotElement(xpath=output_panel)
-
-        # Reveal output panel again.  This brings us back to the same
-        # state as when it was first revealed.
-        client.click(xpath=show_button)
-        self._checkOutputPanel(client, output_panel)
-

=== removed file 'lib/lp/translations/windmill/tests/test_languages.py.disabled'
--- lib/lp/translations/windmill/tests/test_languages.py.disabled	2011-02-10 04:00:00 +0000
+++ lib/lp/translations/windmill/tests/test_languages.py.disabled	1970-01-01 00:00:00 +0000
@@ -1,107 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test for languages listing and filtering behaviour."""
-
-__metaclass__ = type
-__all__ = []
-
-from lp.testing import WindmillTestCase
-from lp.testing.windmill.constants import (
-    FOR_ELEMENT,
-    PAGE_LOAD,
-    SLEEP,
-    )
-from lp.translations.windmill.testing import TranslationsWindmillLayer
-
-
-INPUT_FIELD = (u"//div[contains(@class,'searchform')]"+
-             u"//input[@id='field.search_lang']")
-FILTER_BUTTON = (u"//div[contains(@class,'searchform')]"+
-               u"//input[@value='Filter languages']")
-LANGUAGE = u"//a[contains(@class, 'language') and text()='%s']/parent::li"
-UNSEEN_VALIDATOR = 'className|unseen'
-
-
-class LanguagesFilterTest(WindmillTestCase):
-    """Test that filtering on the +languages page works."""
-
-    layer = TranslationsWindmillLayer
-    suite_name = 'Languages filter'
-
-    def _enter_filter_string(self, filterstring):
-        self.client.type(xpath=INPUT_FIELD, text=filterstring)
-        self.client.click(xpath=FILTER_BUTTON)
-        self.client.waits.sleep(milliseconds=SLEEP)
-
-    def _assert_languages_visible(self, languages):
-        for language, visibility in languages.items():
-            xpath = LANGUAGE % language
-            if visibility:
-                self.client.asserts.assertNotProperty(
-                    xpath=xpath, validator=UNSEEN_VALIDATOR)
-            else:
-                self.client.asserts.assertProperty(
-                    xpath=xpath, validator=UNSEEN_VALIDATOR)
-
-    def test_filter_languages(self):
-        """Test that filtering on the +languages page works.
-
-        The test cannot fully cover all languages on the page and so just
-        tests three with a search string of 'de':
-        German, because it's language code is 'de' but the names does not,
-        Mende, because it contains a 'de' but the language code does not,
-        French, because neither its name nor language code contain 'de'.
-        """
-        client = self.client
-        start_url = '%s/+languages' % TranslationsWindmillLayer.base_url
-        # Go to the languages page
-        self.client.open(url=start_url)
-        self.client.waits.forPageLoad(timeout=PAGE_LOAD)
-
-        # "Not-matching" message is hidden and languages are visible.
-        self.client.asserts.assertProperty(
-            id=u'no_filter_matches',
-            validator='className|unseen',
-            timeout=FOR_ELEMENT)
-        self._assert_languages_visible({
-            u'German': True,
-            u'Mende': True,
-            u'French': True,
-            })
-
-        # Enter search string, search and wait.
-        self._enter_filter_string(u"de")
-        # "Not-matching" message and French are hidden now.
-        self.client.asserts.assertProperty(
-            id=u'no_filter_matches',
-            validator='className|unseen')
-        self._assert_languages_visible({
-            u'German': True,
-            u'Mende': True,
-            u'French': False,
-            })
-
-        # Enter not matching search string, search and wait.
-        self._enter_filter_string(u"xxxxxx")
-        # "Not-matching" message is shown, all languages are hidden.
-        self.client.asserts.assertNotProperty(
-            id=u'no_filter_matches',
-            validator='className|unseen')
-        self._assert_languages_visible({
-            u'German': False,
-            u'Mende': False,
-            u'French': False,
-            })
-
-        # Enter empty search string, search and wait.
-        self._enter_filter_string(u"")
-        # "Not-matching" message is hidden, all languages are visible again.
-        self.client.asserts.assertProperty(
-             id=u'no_filter_matches',
-             validator='className|unseen')
-        self._assert_languages_visible({
-            u'German': True,
-            u'Mende': True,
-            u'French': True,
-            })

=== modified file 'lib/lp/translations/windmill/tests/test_pofile_translate.py'
--- lib/lp/translations/windmill/tests/test_pofile_translate.py	2011-03-30 05:18:07 +0000
+++ lib/lp/translations/windmill/tests/test_pofile_translate.py	2011-06-27 15:56:40 +0000
@@ -20,75 +20,13 @@
 from lp.translations.windmill.testing import TranslationsWindmillLayer
 
 
-class POFileNewTranslationFieldKeybindings(WindmillTestCase):
-    """Tests for keybinding actions associated to the translation field.
+class POFileTranslationActions(WindmillTestCase):
+    """Tests for actions that can be done on a translation message.
 
-    These tests should cover both simple (ie. pt) and composed (ie. pt_br)
-    language codes.
+    XXX: Move to YUI test.
     """
 
     layer = TranslationsWindmillLayer
-    suite_name = 'POFile Translate'
-
-    def _checkTranslationAutoselect(
-        self, url, new_translation_id, new_translation_select_id):
-        """Checks that the select radio button is checked when typing a new
-        translation.
-        """
-        # Go to the translation page.
-        client, start_url = self.getClientFor(url, user=self.test_user)
-
-        # Wait for the new translation field and it's associated radio button.
-        client.waits.forElement(
-            id=new_translation_id, timeout=constants.FOR_ELEMENT)
-        client.waits.forElement(
-            id=new_translation_select_id, timeout=constants.FOR_ELEMENT)
-
-        # Check that the associated radio button is not selected.
-        client.asserts.assertNotChecked(id=new_translation_select_id)
-
-        # Type a new translation.
-        client.type(id=new_translation_id, text=u'New translation')
-
-        # Check that the associated radio button is selected.
-        client.asserts.assertChecked(id=new_translation_select_id)
-
-    def test_pofile_new_translation_autoselect(self):
-        """Test for automatically selecting new translation on text input.
-
-        When new text is typed into the new translation text fields, the
-        associated radio button should be automatically selected.
-        """
-        self.test_user = lpuser.TRANSLATIONS_ADMIN
-
-        # Test the zoom out view for Evolution trunk Spanish (es).
-        start_url = '/evolution/trunk/+pots/evolution-2.2/es/+translate'
-        new_translation_id = u'msgset_1_es_translation_0_new'
-        new_translation_select_id = u'msgset_1_es_translation_0_new_select'
-        self._checkTranslationAutoselect(
-            start_url, new_translation_id, new_translation_select_id)
-
-        # Test the zoom in view for Evolution trunk Brazilian (pt_BR).
-        start_url = '/evolution/trunk/+pots/evolution-2.2/pt_BR/1/+translate'
-        new_translation_id = u'msgset_1_pt_BR_translation_0_new'
-        new_translation_select_id = u'msgset_1_pt_BR_translation_0_new_select'
-        self._checkTranslationAutoselect(
-            start_url, new_translation_id, new_translation_select_id)
-
-        # Test the zoom out view for Ubuntu Hoary Brazilian (pt_BR).
-        start_url = ('/ubuntu/hoary/+source/mozilla/+pots/pkgconf-mozilla/'
-                        'pt_BR/1/+translate')
-        new_translation_id = u'msgset_152_pt_BR_translation_0_new'
-        new_translation_select_id = (u'msgset_152_pt_BR'
-                                       '_translation_0_new_select')
-        self._checkTranslationAutoselect(
-            start_url, new_translation_id, new_translation_select_id)
-
-
-class POFileTranslationActions(WindmillTestCase):
-    """Tests for actions that can be done on a translation message."""
-
-    layer = TranslationsWindmillLayer
     suite_name = 'POFile Translation Actions'
 
     def test_dismiss_uncheck_force_suggestion(self):
@@ -290,6 +228,7 @@
     def test_pofile_reset_translation_select(self):
         """Test for automatically selecting new translation when
         'Someone needs to review this translations' is checked.
+
         """
         # Go to the zoom in page for a translation with plural forms.
         client, start_url = self.getClientFor(
@@ -384,88 +323,3 @@
         client.asserts.assertNotChecked(
             id=u'msgset_139_es_translation_0_new_select')
 
-
-class POFileTranslatorAndReviewerWorkingMode(WindmillTestCase):
-    """Tests for page behaviour in reviewer or translator mode."""
-
-    layer = TranslationsWindmillLayer
-    suite_name = 'POFile Translate'
-
-    test_user = lpuser.TRANSLATIONS_ADMIN
-
-    switch_working_mode = u'translation-switch-working-mode'
-    force_suggestion = u'msgset_1_force_suggestion'
-    new_translation = u'msgset_1_pt_BR_translation_0_new'
-    js_code = ("lookupNode({id: '%s'}).innerHTML.search('eviewer') > 0" %
-                switch_working_mode)
-
-    def test_pofile_reviewer_mode(self):
-        """Test for reviewer mode.
-
-        Adding new translations will force them as suggestions.
-        """
-
-        self.client, start_url = self.getClientFor(
-            '/evolution/trunk/+pots/evolution-2.2/pt_BR/1/+translate',
-            user=self.test_user)
-
-        self._ensureTranslationMode(reviewer=True)
-
-        self.client.waits.forElement(
-            id=self.force_suggestion, timeout=constants.FOR_ELEMENT)
-        self.client.type(text=u'New translation', id=self.new_translation)
-        self.client.asserts.assertNotChecked(id=self.force_suggestion)
-
-    def test_pofile_translator_mode(self):
-        """Test for translator mode.
-
-        Adding new translations will not force them as suggestions.
-        """
-
-        self.client, start_url = self.getClientFor(
-            '/evolution/trunk/+pots/evolution-2.2/pt_BR/1/+translate',
-            user=self.test_user)
-
-        self._ensureTranslationMode(translator=True)
-
-        self.client.waits.forElement(
-            id=self.force_suggestion, timeout=constants.FOR_ELEMENT)
-        self.client.type(text=u'New translation', id=self.new_translation)
-        self.client.asserts.assertChecked(id=self.force_suggestion)
-
-        # The new translation will be forced only if the previous new
-        # translation field is empty. Othewise the force suggestion checkbox
-        # will remain unchecked.
-        self.client.click(id=self.force_suggestion)
-        self.client.keyPress(
-            id=self.new_translation,
-            options='a,true,false,false,false,false')
-        self.client.asserts.assertNotChecked(id=self.force_suggestion)
-
-    def _ensureTranslationMode(self, reviewer=False, translator=False):
-        """Ensure the specified mode is currently selected."""
-
-        if reviewer is translator:
-            raise AssertionError("You must specify a single working mode.")
-
-        self.client.waits.forElement(
-            id=self.switch_working_mode, timeout=constants.FOR_ELEMENT)
-
-        current_is_reviewer = self.client.commands.execJS(
-            js=self.js_code)['result']
-        need_to_switch_mode = (
-            reviewer and not current_is_reviewer or
-            translator and current_is_reviewer)
-        if need_to_switch_mode:
-            self.client.click(id=self.switch_working_mode)
-        else:
-            return
-
-        # We check that the mode was changed.
-        current_is_reviewer = self.client.commands.execJS(
-            js=self.js_code)['result']
-
-        switch_done = (
-            reviewer and current_is_reviewer or
-            translator and not current_is_reviewer)
-        assert switch_done is True, "Could not switch working mode."

=== removed file 'lib/lp/translations/windmill/tests/test_serieslanguages.py'
--- lib/lp/translations/windmill/tests/test_serieslanguages.py	2011-03-29 05:59:29 +0000
+++ lib/lp/translations/windmill/tests/test_serieslanguages.py	1970-01-01 00:00:00 +0000
@@ -1,76 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Tests for series languages."""
-
-__metaclass__ = type
-__all__ = []
-
-from lp.testing import WindmillTestCase
-from lp.testing.windmill import lpuser
-from lp.testing.windmill.constants import (
-    SLEEP,
-    )
-from lp.translations.windmill.testing import TranslationsWindmillLayer
-
-
-LANGUAGE=(u"//table[@id='languagestats']/descendant::a[text()='%s']"
-         u"/parent::td/parent::tr")
-UNSEEN_VALIDATOR='className|unseen'
-
-
-class LanguagesSeriesTest(WindmillTestCase):
-    """Tests for serieslanguages."""
-
-    layer = TranslationsWindmillLayer
-    suite_name = 'SeriesLanguages Tables'
-
-    def _toggle_languages_visiblity(self, client):
-        client.click(id="toggle-languages-visibility")
-        client.waits.sleep(milliseconds=SLEEP)
-
-    def _assert_languages_visible(self, languages):
-        for language, visibility in languages.items():
-            xpath = LANGUAGE % language
-            if visibility:
-                self.client.asserts.assertNotProperty(
-                    xpath=xpath, validator=UNSEEN_VALIDATOR)
-            else:
-                self.client.asserts.assertProperty(
-                    xpath=xpath, validator=UNSEEN_VALIDATOR)
-
-    def test_serieslanguages_table(self):
-        """Test for filtering preferred languages in serieslanguages table.
-
-        The test cannot fully cover all languages so we just test with a
-        person having Catalan and Spanish as preferred languages.
-        """
-
-        # Go to the distribution languages page
-        client, start_url = self.getClientFor(
-            '/ubuntu', user=lpuser.TRANSLATIONS_ADMIN)
-
-        # A link will be displayed for viewing all languages
-        # and only user preferred langauges are displayed
-        client.asserts.assertProperty(
-            id=u'toggle-languages-visibility',
-            validator='text|View all languages')
-        self._assert_languages_visible({
-            u'Catalan': True,
-            u'Spanish': True,
-            u'French': False,
-            u'Croatian': False,
-            })
-
-        # Toggle language visibility by clicking the toggle link.
-        self._toggle_languages_visiblity(client)
-        client.asserts.assertProperty(
-            id=u'toggle-languages-visibility',
-            validator='text|View only preferred languages')
-        # All languages should be visible now
-        self._assert_languages_visible({
-            u'Catalan': True,
-            u'Spanish': True,
-            u'French': True,
-            u'Croatian': True,
-            })

=== modified file 'versions.cfg'
--- versions.cfg	2011-06-27 14:45:31 +0000
+++ versions.cfg	2011-06-27 15:56:40 +0000
@@ -82,9 +82,6 @@
 van.testing = 2.0.1
 wadllib = 1.2.0
 webunit = 1.3.8
-# r1579 of lp:windmill, with a fix for the 512k bug.
-# Built from lp:~launchpad/windmill/512k-bug-fix.
-windmill = 1.5pre-deryck
 wsgi-fileserver = 0.2.7
 wsgi-intercept = 0.4
 wsgi-jsonrpc = 0.2.8