1
0
mirror of https://github.com/django/django.git synced 2025-04-01 12:06:43 +00:00

Refs #34043 -- Added context managers to SeleniumTestCase for changing window size.

This commit is contained in:
Sarah Boyce 2023-10-13 10:21:34 +02:00 committed by Mariusz Felisiak
parent 20b7aac7ca
commit f6629ee2c9
3 changed files with 166 additions and 137 deletions

View File

@ -98,6 +98,20 @@ class SeleniumTestCaseBase(type(LiveServerTestCase)):
return self.import_webdriver(self.browser)(options=options) return self.import_webdriver(self.browser)(options=options)
class ChangeWindowSize:
def __init__(self, width, height, selenium):
self.selenium = selenium
self.new_size = (width, height)
def __enter__(self):
self.old_size = self.selenium.get_window_size()
self.selenium.set_window_size(*self.new_size)
return self
def __exit__(self, exc_type, exc_value, traceback):
self.selenium.set_window_size(self.old_size["width"], self.old_size["height"])
@tag("selenium") @tag("selenium")
class SeleniumTestCase(LiveServerTestCase, metaclass=SeleniumTestCaseBase): class SeleniumTestCase(LiveServerTestCase, metaclass=SeleniumTestCaseBase):
implicit_wait = 10 implicit_wait = 10
@ -118,6 +132,21 @@ class SeleniumTestCase(LiveServerTestCase, metaclass=SeleniumTestCaseBase):
super().setUpClass() super().setUpClass()
cls.addClassCleanup(cls._quit_selenium) cls.addClassCleanup(cls._quit_selenium)
@contextmanager
def desktop_size(self):
with ChangeWindowSize(1280, 720, self.selenium):
yield
@contextmanager
def small_screen_size(self):
with ChangeWindowSize(1024, 768, self.selenium):
yield
@contextmanager
def mobile_size(self):
with ChangeWindowSize(360, 800, self.selenium):
yield
@classmethod @classmethod
def _quit_selenium(cls): def _quit_selenium(cls):
# quit() the WebDriver before attempting to terminate and join the # quit() the WebDriver before attempting to terminate and join the

View File

@ -6489,14 +6489,10 @@ class SeleniumTests(AdminSeleniumTestCase):
) )
self.selenium.get(self.live_server_url + reverse("admin:admin_views_story_add")) self.selenium.get(self.live_server_url + reverse("admin:admin_views_story_add"))
field_title = self.selenium.find_element(By.CLASS_NAME, "field-title") field_title = self.selenium.find_element(By.CLASS_NAME, "field-title")
current_size = self.selenium.get_window_size() with self.small_screen_size():
try:
self.selenium.set_window_size(1024, 768)
self.assertIs(field_title.is_displayed(), False) self.assertIs(field_title.is_displayed(), False)
self.selenium.set_window_size(767, 575) with self.mobile_size():
self.assertIs(field_title.is_displayed(), False) self.assertIs(field_title.is_displayed(), False)
finally:
self.selenium.set_window_size(current_size["width"], current_size["height"])
def test_updating_related_objects_updates_fk_selects_except_autocompletes(self): def test_updating_related_objects_updates_fk_selects_except_autocompletes(self):
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By

View File

@ -1083,7 +1083,6 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
""" """
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
self.selenium.set_window_size(1024, 768)
self.admin_login(username="super", password="secret", login_url="/") self.admin_login(username="super", password="secret", login_url="/")
# Enter test data # Enter test data
@ -1096,29 +1095,30 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
path = os.path.join( path = os.path.join(
os.path.dirname(import_module("django.contrib.admin").__file__), "locale" os.path.dirname(import_module("django.contrib.admin").__file__), "locale"
) )
for language_code, language_name in settings.LANGUAGES: url = reverse("admin:admin_widgets_member_change", args=(member.pk,))
try: with self.small_screen_size():
catalog = gettext.translation("djangojs", path, [language_code]) for language_code, language_name in settings.LANGUAGES:
except OSError: try:
continue catalog = gettext.translation("djangojs", path, [language_code])
if month_string in catalog._catalog: except OSError:
month_name = catalog._catalog[month_string] continue
else: if month_string in catalog._catalog:
month_name = month_string month_name = catalog._catalog[month_string]
else:
month_name = month_string
# Get the expected caption # Get the expected caption.
may_translation = month_name may_translation = month_name
expected_caption = "{:s} {:d}".format(may_translation.upper(), 1984) expected_caption = "{:s} {:d}".format(may_translation.upper(), 1984)
# Test with every locale # Every locale.
with override_settings(LANGUAGE_CODE=language_code): with override_settings(LANGUAGE_CODE=language_code):
# Open a page that has a date picker widget # Open a page that has a date picker widget.
url = reverse("admin:admin_widgets_member_change", args=(member.pk,)) self.selenium.get(self.live_server_url + url)
self.selenium.get(self.live_server_url + url) # Click on the calendar icon.
# Click on the calendar icon self.selenium.find_element(By.ID, "calendarlink0").click()
self.selenium.find_element(By.ID, "calendarlink0").click() # The right month and year are displayed.
# Make sure that the right month and year are displayed self.wait_for_text("#calendarin0 caption", expected_caption)
self.wait_for_text("#calendarin0 caption", expected_caption)
@requires_tz_support @requires_tz_support
@ -1416,23 +1416,24 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
def test_basic(self): def test_basic(self):
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
self.selenium.set_window_size(1024, 768)
self.school.students.set([self.lisa, self.peter]) self.school.students.set([self.lisa, self.peter])
self.school.alumni.set([self.lisa, self.peter]) self.school.alumni.set([self.lisa, self.peter])
self.admin_login(username="super", password="secret", login_url="/") with self.small_screen_size():
self.selenium.get( self.admin_login(username="super", password="secret", login_url="/")
self.live_server_url self.selenium.get(
+ reverse("admin:admin_widgets_school_change", args=(self.school.id,)) self.live_server_url
) + reverse("admin:admin_widgets_school_change", args=(self.school.id,))
)
self.wait_page_ready() self.wait_page_ready()
self.execute_basic_operations("vertical", "students") self.execute_basic_operations("vertical", "students")
self.execute_basic_operations("horizontal", "alumni") self.execute_basic_operations("horizontal", "alumni")
# Save and check that everything is properly stored in the database --- # Save, everything should be stored properly stored in the
self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click() # database.
self.wait_page_ready() self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click()
self.wait_page_ready()
self.school = School.objects.get(id=self.school.id) # Reload from database self.school = School.objects.get(id=self.school.id) # Reload from database
self.assertEqual( self.assertEqual(
list(self.school.students.all()), list(self.school.students.all()),
@ -1451,113 +1452,116 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
self.selenium.set_window_size(1024, 768)
self.school.students.set([self.lisa, self.peter]) self.school.students.set([self.lisa, self.peter])
self.school.alumni.set([self.lisa, self.peter]) self.school.alumni.set([self.lisa, self.peter])
self.admin_login(username="super", password="secret", login_url="/") with self.small_screen_size():
self.selenium.get( self.admin_login(username="super", password="secret", login_url="/")
self.live_server_url self.selenium.get(
+ reverse("admin:admin_widgets_school_change", args=(self.school.id,)) self.live_server_url
) + reverse("admin:admin_widgets_school_change", args=(self.school.id,))
for field_name in ["students", "alumni"]:
from_box = "#id_%s_from" % field_name
to_box = "#id_%s_to" % field_name
choose_link = "id_%s_add_link" % field_name
remove_link = "id_%s_remove_link" % field_name
input = self.selenium.find_element(By.ID, "id_%s_input" % field_name)
# Initial values
self.assertSelectOptions(
from_box,
[
str(self.arthur.id),
str(self.bob.id),
str(self.cliff.id),
str(self.jason.id),
str(self.jenny.id),
str(self.john.id),
],
) )
# Typing in some characters filters out non-matching options for field_name in ["students", "alumni"]:
input.send_keys("a") from_box = "#id_%s_from" % field_name
self.assertSelectOptions( to_box = "#id_%s_to" % field_name
from_box, [str(self.arthur.id), str(self.jason.id)] choose_link = "id_%s_add_link" % field_name
) remove_link = "id_%s_remove_link" % field_name
input.send_keys("R") input = self.selenium.find_element(By.ID, "id_%s_input" % field_name)
self.assertSelectOptions(from_box, [str(self.arthur.id)]) # Initial values.
self.assertSelectOptions(
from_box,
[
str(self.arthur.id),
str(self.bob.id),
str(self.cliff.id),
str(self.jason.id),
str(self.jenny.id),
str(self.john.id),
],
)
# Typing in some characters filters out non-matching options.
input.send_keys("a")
self.assertSelectOptions(
from_box, [str(self.arthur.id), str(self.jason.id)]
)
input.send_keys("R")
self.assertSelectOptions(from_box, [str(self.arthur.id)])
# Clearing the text box makes the other options reappear.
input.send_keys([Keys.BACK_SPACE])
self.assertSelectOptions(
from_box, [str(self.arthur.id), str(self.jason.id)]
)
input.send_keys([Keys.BACK_SPACE])
self.assertSelectOptions(
from_box,
[
str(self.arthur.id),
str(self.bob.id),
str(self.cliff.id),
str(self.jason.id),
str(self.jenny.id),
str(self.john.id),
],
)
# Clearing the text box makes the other options reappear # Choosing a filtered option sends it properly to the 'to' box.
input.send_keys([Keys.BACK_SPACE]) input.send_keys("a")
self.assertSelectOptions( self.assertSelectOptions(
from_box, [str(self.arthur.id), str(self.jason.id)] from_box, [str(self.arthur.id), str(self.jason.id)]
) )
input.send_keys([Keys.BACK_SPACE]) self.select_option(from_box, str(self.jason.id))
self.assertSelectOptions( self.selenium.find_element(By.ID, choose_link).click()
from_box, self.assertSelectOptions(from_box, [str(self.arthur.id)])
[ self.assertSelectOptions(
str(self.arthur.id), to_box,
str(self.bob.id), [
str(self.cliff.id), str(self.lisa.id),
str(self.jason.id), str(self.peter.id),
str(self.jenny.id), str(self.jason.id),
str(self.john.id), ],
], )
)
# ----------------------------------------------------------------- self.select_option(to_box, str(self.lisa.id))
# Choosing a filtered option sends it properly to the 'to' box. self.selenium.find_element(By.ID, remove_link).click()
input.send_keys("a") self.assertSelectOptions(
self.assertSelectOptions( from_box, [str(self.arthur.id), str(self.lisa.id)]
from_box, [str(self.arthur.id), str(self.jason.id)] )
) self.assertSelectOptions(
self.select_option(from_box, str(self.jason.id)) to_box, [str(self.peter.id), str(self.jason.id)]
self.selenium.find_element(By.ID, choose_link).click() )
self.assertSelectOptions(from_box, [str(self.arthur.id)])
self.assertSelectOptions(
to_box,
[
str(self.lisa.id),
str(self.peter.id),
str(self.jason.id),
],
)
self.select_option(to_box, str(self.lisa.id)) input.send_keys([Keys.BACK_SPACE]) # Clear text box
self.selenium.find_element(By.ID, remove_link).click() self.assertSelectOptions(
self.assertSelectOptions(from_box, [str(self.arthur.id), str(self.lisa.id)]) from_box,
self.assertSelectOptions(to_box, [str(self.peter.id), str(self.jason.id)]) [
str(self.arthur.id),
str(self.bob.id),
str(self.cliff.id),
str(self.jenny.id),
str(self.john.id),
str(self.lisa.id),
],
)
self.assertSelectOptions(
to_box, [str(self.peter.id), str(self.jason.id)]
)
input.send_keys([Keys.BACK_SPACE]) # Clear text box # Pressing enter on a filtered option sends it properly to
self.assertSelectOptions( # the 'to' box.
from_box, self.select_option(to_box, str(self.jason.id))
[ self.selenium.find_element(By.ID, remove_link).click()
str(self.arthur.id), input.send_keys("ja")
str(self.bob.id), self.assertSelectOptions(from_box, [str(self.jason.id)])
str(self.cliff.id), input.send_keys([Keys.ENTER])
str(self.jenny.id), self.assertSelectOptions(
str(self.john.id), to_box, [str(self.peter.id), str(self.jason.id)]
str(self.lisa.id), )
], input.send_keys([Keys.BACK_SPACE, Keys.BACK_SPACE])
)
self.assertSelectOptions(to_box, [str(self.peter.id), str(self.jason.id)])
# ----------------------------------------------------------------- # Save, everything should be stored properly in the database.
# Pressing enter on a filtered option sends it properly to with self.wait_page_loaded():
# the 'to' box. self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click()
self.select_option(to_box, str(self.jason.id))
self.selenium.find_element(By.ID, remove_link).click()
input.send_keys("ja")
self.assertSelectOptions(from_box, [str(self.jason.id)])
input.send_keys([Keys.ENTER])
self.assertSelectOptions(to_box, [str(self.peter.id), str(self.jason.id)])
input.send_keys([Keys.BACK_SPACE, Keys.BACK_SPACE])
# Save and check that everything is properly stored in the database ---
with self.wait_page_loaded():
self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click()
self.school = School.objects.get(id=self.school.id) # Reload from database self.school = School.objects.get(id=self.school.id) # Reload from database
self.assertEqual(list(self.school.students.all()), [self.jason, self.peter]) self.assertEqual(list(self.school.students.all()), [self.jason, self.peter])
self.assertEqual(list(self.school.alumni.all()), [self.jason, self.peter]) self.assertEqual(list(self.school.alumni.all()), [self.jason, self.peter])