From 0d368bfb472513e0adb6b1d9d246511f2556e3d7 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Wed, 19 Aug 2015 20:43:27 -0400
Subject: [PATCH] [1.8.x] Fixed #25323 -- Fixed selenium test failures with
 chromedriver 2.18.

Backport of 7ac0cd445e056cac9bfc1fed11026ab6c74b8818 from master
---
 django/contrib/admin/tests.py |  7 +++++++
 tests/admin_views/tests.py    | 10 ++++++++--
 tests/admin_widgets/tests.py  | 21 ++++++++-------------
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/django/contrib/admin/tests.py b/django/contrib/admin/tests.py
index d7780da210..5415d5fcaa 100644
--- a/django/contrib/admin/tests.py
+++ b/django/contrib/admin/tests.py
@@ -45,6 +45,13 @@ class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase):
         from selenium.webdriver.support.wait import WebDriverWait
         WebDriverWait(self.selenium, timeout).until(callback)
 
+    def wait_for_popup(self, num_windows=2, timeout=10):
+        """
+        Block until `num_windows` are present (usually 2, but can be
+        overridden in the case of pop-ups opening other pop-ups).
+        """
+        self.wait_until(lambda d: len(d.window_handles) == num_windows, timeout)
+
     def wait_loaded_tag(self, tag_name, timeout=10):
         """
         Helper function that blocks until the element with the given tag name
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index dd96715605..8e3255c99b 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -3979,8 +3979,11 @@ class SeleniumAdminViewsFirefoxTests(AdminSeleniumWebDriverTestCase):
         self.admin_login(username='super', password='secret', login_url=reverse('admin:index'))
         self.selenium.get(full_url)
         self.selenium.find_element_by_class_name('deletelink').click()
+        # Wait until we're on the delete page.
+        self.wait_for('.cancel-link')
         self.selenium.find_element_by_class_name('cancel-link').click()
-        self.wait_page_loaded()
+        # Wait until we're back on the change page.
+        self.wait_for_text('#content h1', 'Change pizza')
         self.assertEqual(self.selenium.current_url, full_url)
         self.assertEqual(Pizza.objects.count(), 1)
 
@@ -3998,8 +4001,11 @@ class SeleniumAdminViewsFirefoxTests(AdminSeleniumWebDriverTestCase):
         self.admin_login(username='super', password='secret', login_url=reverse('admin:index'))
         self.selenium.get(full_url)
         self.selenium.find_element_by_class_name('deletelink').click()
+        # Wait until we're on the delete page.
+        self.wait_for('.cancel-link')
         self.selenium.find_element_by_class_name('cancel-link').click()
-        self.wait_page_loaded()
+        # Wait until we're back on the change page.
+        self.wait_for_text('#content h1', 'Change pizza')
         self.assertEqual(self.selenium.current_url, full_url)
         self.assertEqual(Pizza.objects.count(), 1)
         self.assertEqual(Topping.objects.count(), 2)
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 6838a12b4d..dd24b17e87 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -730,13 +730,8 @@ class DateTimePickerSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
 
                 # Click on the calendar icon
                 self.selenium.find_element_by_id('calendarlink0').click()
-
-                # Get the calendar caption
-                calendar0 = self.selenium.find_element_by_id('calendarin0')
-                caption = calendar0.find_element_by_tag_name('caption')
-
                 # Make sure that the right month and year are displayed
-                self.assertEqual(caption.text, expected_caption)
+                self.wait_for_text('#calendarin0 caption', expected_caption)
 
 
 class DateTimePickerSeleniumChromeTests(DateTimePickerSeleniumFirefoxTests):
@@ -1097,8 +1092,8 @@ class AdminRawIdWidgetSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
 
         # Open the popup window and click on a band
         self.selenium.find_element_by_id('lookup_id_main_band').click()
+        self.wait_for_popup()
         self.selenium.switch_to.window('id_main_band')
-        self.wait_page_loaded()
         link = self.selenium.find_element_by_link_text('Bogey Blues')
         self.assertIn('/band/42/', link.get_attribute('href'))
         link.click()
@@ -1109,8 +1104,8 @@ class AdminRawIdWidgetSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
 
         # Reopen the popup window and click on another band
         self.selenium.find_element_by_id('lookup_id_main_band').click()
+        self.wait_for_popup()
         self.selenium.switch_to.window('id_main_band')
-        self.wait_page_loaded()
         link = self.selenium.find_element_by_link_text('Green Potatoes')
         self.assertIn('/band/98/', link.get_attribute('href'))
         link.click()
@@ -1132,8 +1127,8 @@ class AdminRawIdWidgetSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
 
         # Open the popup window and click on a band
         self.selenium.find_element_by_id('lookup_id_supporting_bands').click()
+        self.wait_for_popup()
         self.selenium.switch_to.window('id_supporting_bands')
-        self.wait_page_loaded()
         link = self.selenium.find_element_by_link_text('Bogey Blues')
         self.assertIn('/band/42/', link.get_attribute('href'))
         link.click()
@@ -1144,8 +1139,8 @@ class AdminRawIdWidgetSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
 
         # Reopen the popup window and click on another band
         self.selenium.find_element_by_id('lookup_id_supporting_bands').click()
+        self.wait_for_popup()
         self.selenium.switch_to.window('id_supporting_bands')
-        self.wait_page_loaded()
         link = self.selenium.find_element_by_link_text('Green Potatoes')
         self.assertIn('/band/98/', link.get_attribute('href'))
         link.click()
@@ -1179,8 +1174,8 @@ class RelatedFieldWidgetSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
         main_window = self.selenium.current_window_handle
         # Click the Add User button to add new
         self.selenium.find_element_by_id('add_id_user').click()
+        self.wait_for_popup()
         self.selenium.switch_to.window('id_user')
-        self.wait_for('#id_password')
         password_field = self.selenium.find_element_by_id('id_password')
         password_field.send_keys('password')
 
@@ -1196,8 +1191,8 @@ class RelatedFieldWidgetSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
 
         # Click the Change User button to change it
         self.selenium.find_element_by_id('change_id_user').click()
-        self.selenium.switch_to_window('id_user')
-        self.wait_page_loaded()
+        self.wait_for_popup()
+        self.selenium.switch_to.window('id_user')
 
         username_field = self.selenium.find_element_by_id('id_username')
         username_value = 'changednewuser'