created functional_tests.list_page to handle common FT helpers; almost every FT file affected & less reliant on .base, which no longer contains those helpers

This commit is contained in:
Disco DeDisco
2026-02-17 23:07:12 -05:00
parent e26ee5af1d
commit e32c6bbfd6
7 changed files with 100 additions and 46 deletions

View File

@@ -78,21 +78,6 @@ class FunctionalTest(StaticLiveServerTestCase):
def wait_for(self, fn): def wait_for(self, fn):
return fn() return fn()
def get_item_input_box(self):
return self.browser.find_element(By.ID, "id_text")
@wait
def wait_for_row_in_list_table(self, row_text):
rows = self.browser.find_elements(By.CSS_SELECTOR, "#id_list_table tr")
self.assertIn(row_text, [row.text for row in rows])
def add_list_item(self, item_text):
num_rows = len(self.browser.find_elements(By.CSS_SELECTOR, "#id_list_table tr"))
self.get_item_input_box().send_keys(item_text)
self.get_item_input_box().send_keys(Keys.ENTER)
item_number = num_rows + 1
self.wait_for_row_in_list_table(f"{item_number}. {item_text}")
def create_pre_authenticated_session(self, email): def create_pre_authenticated_session(self, email):
if self.test_server: if self.test_server:
session_key = create_session_on_server(self.test_server, email) session_key = create_session_on_server(self.test_server, email)

View File

@@ -0,0 +1,49 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from .base import wait
class ListPage:
def __init__(self, test):
self.test = test
def get_table_rows(self):
return self.test.browser.find_elements(By.CSS_SELECTOR, "#id_list_table tr")
@wait
def wait_for_row_in_list_table(self, item_text, item_number):
expected_row_text = f"{item_number}. {item_text}"
rows = self.get_table_rows()
self.test.assertIn(expected_row_text, [row.text for row in rows])
def get_item_input_box(self):
return self.test.browser.find_element(By.ID, "id_text")
def add_list_item(self, item_text):
new_item_no = len(self.get_table_rows()) + 1
self.get_item_input_box().send_keys(item_text)
self.get_item_input_box().send_keys(Keys.ENTER)
self.wait_for_row_in_list_table(item_text, new_item_no)
return self
def get_share_box(self):
return self.test.browser.find_element(
By.CSS_SELECTOR,
'input[name="recipient]',
)
def get_shared_with_list(self):
return self.test.browser.find_elements(
By.CSS_SELECTOR,
".list-recipient"
)
def share_list_with(self, email):
self.get_share_box().send_keys(email)
self.get_share_box().send_keys(Keys.ENTER)
self.test.wait_for(
lambda: self.test.assertIn(
email, [item.text for item in self.get_shared_with_list()]
)
)

View File

@@ -2,23 +2,25 @@ from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from .base import FunctionalTest from .base import FunctionalTest
from .list_page import ListPage
class LayoutAndStylingTest(FunctionalTest): class LayoutAndStylingTest(FunctionalTest):
def test_layout_and_styling(self): def test_layout_and_styling(self):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
list_page = ListPage(self)
self.browser.set_window_size(1024, 768) self.browser.set_window_size(1024, 768)
# print("Viewport width:", self.browser.execute_script("return window.innerWidth")) # print("Viewport width:", self.browser.execute_script("return window.innerWidth"))
inputbox = self.get_item_input_box() inputbox = list_page.get_item_input_box()
self.assertAlmostEqual( self.assertAlmostEqual(
inputbox.location['x'] + inputbox.size['width'] / 2, inputbox.location['x'] + inputbox.size['width'] / 2,
512, 512,
delta=10, delta=10,
) )
self.add_list_item("testing") list_page.add_list_item("testing")
inputbox = self.get_item_input_box() inputbox = list_page.get_item_input_box()
self.assertAlmostEqual( self.assertAlmostEqual(
inputbox.location['x'] + inputbox.size['width'] / 2, inputbox.location['x'] + inputbox.size['width'] / 2,
512, 512,

View File

@@ -2,6 +2,8 @@ from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from .base import FunctionalTest from .base import FunctionalTest
from .list_page import ListPage
class ItemValidationTest(FunctionalTest): class ItemValidationTest(FunctionalTest):
# Helper functions # Helper functions
@@ -11,43 +13,45 @@ class ItemValidationTest(FunctionalTest):
# Test methods # Test methods
def test_cannot_add_empty_list_items(self): def test_cannot_add_empty_list_items(self):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self.get_item_input_box().send_keys(Keys.ENTER) list_page = ListPage(self)
list_page.get_item_input_box().send_keys(Keys.ENTER)
self.wait_for( self.wait_for(
lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_text:invalid") lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_text:invalid")
) )
self.get_item_input_box().send_keys("Purchase milk") list_page.get_item_input_box().send_keys("Purchase milk")
self.wait_for( self.wait_for(
lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_text:valid") lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_text:valid")
) )
self.get_item_input_box().send_keys(Keys.ENTER) list_page.get_item_input_box().send_keys(Keys.ENTER)
self.wait_for_row_in_list_table("1. Purchase milk") list_page.wait_for_row_in_list_table("Purchase milk", 1)
self.get_item_input_box().send_keys(Keys.ENTER) list_page.get_item_input_box().send_keys(Keys.ENTER)
self.wait_for_row_in_list_table("1. Purchase milk") list_page.wait_for_row_in_list_table("Purchase milk", 1)
self.wait_for( self.wait_for(
lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_text:invalid") lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_text:invalid")
) )
self.get_item_input_box().send_keys("Make tea") list_page.get_item_input_box().send_keys("Make tea")
self.wait_for( self.wait_for(
lambda: self.browser.find_element( lambda: self.browser.find_element(
By.CSS_SELECTOR, By.CSS_SELECTOR,
"#id_text:valid", "#id_text:valid",
) )
) )
self.get_item_input_box().send_keys(Keys.ENTER) list_page.get_item_input_box().send_keys(Keys.ENTER)
self.wait_for_row_in_list_table("2. Make tea") list_page.wait_for_row_in_list_table("Make tea", 2)
def test_cannot_add_duplicate_items(self): def test_cannot_add_duplicate_items(self):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self.add_list_item("Witness divinity") list_page = ListPage(self)
list_page.add_list_item("Witness divinity")
self.get_item_input_box().send_keys("Witness divinity") list_page.get_item_input_box().send_keys("Witness divinity")
self.get_item_input_box().send_keys(Keys.ENTER) list_page.get_item_input_box().send_keys(Keys.ENTER)
self.wait_for( self.wait_for(
lambda: self.assertEqual( lambda: self.assertEqual(
@@ -58,14 +62,15 @@ class ItemValidationTest(FunctionalTest):
def test_error_messages_are_cleared_on_input(self): def test_error_messages_are_cleared_on_input(self):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self.add_list_item("Gobbledygook") list_page = ListPage(self)
self.get_item_input_box().send_keys("Gobbledygook") list_page.add_list_item("Gobbledygook")
self.get_item_input_box().send_keys(Keys.ENTER) list_page.get_item_input_box().send_keys("Gobbledygook")
list_page.get_item_input_box().send_keys(Keys.ENTER)
self.wait_for( self.wait_for(
lambda: self.assertTrue(self.get_error_element().is_displayed()) lambda: self.assertTrue(self.get_error_element().is_displayed())
) )
self.get_item_input_box().send_keys("a") list_page.get_item_input_box().send_keys("a")
self.wait_for( self.wait_for(
lambda: self.assertFalse(self.get_error_element().is_displayed()) lambda: self.assertFalse(self.get_error_element().is_displayed())

View File

@@ -1,5 +1,8 @@
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from .base import FunctionalTest from .base import FunctionalTest
from .list_page import ListPage
class MyListsTest(FunctionalTest): class MyListsTest(FunctionalTest):
@@ -7,8 +10,9 @@ class MyListsTest(FunctionalTest):
self.create_pre_authenticated_session("discoman@example.com") self.create_pre_authenticated_session("discoman@example.com")
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self.add_list_item("Reticulate splines") list_page = ListPage(self)
self.add_list_item("Regurgitate spines") list_page.add_list_item("Reticulate splines")
list_page.add_list_item("Regurgitate spines")
first_list_url = self.browser.current_url first_list_url = self.browser.current_url
self.browser.find_element(By.LINK_TEXT, "My lists").click() self.browser.find_element(By.LINK_TEXT, "My lists").click()
@@ -29,7 +33,7 @@ class MyListsTest(FunctionalTest):
) )
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self.add_list_item("Ribbon of death") list_page.add_list_item("Ribbon of death")
second_list_url = self.browser.current_url second_list_url = self.browser.current_url
self.browser.find_element(By.LINK_TEXT, "My lists").click() self.browser.find_element(By.LINK_TEXT, "My lists").click()

View File

@@ -1,6 +1,8 @@
from selenium import webdriver from selenium import webdriver
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from .base import FunctionalTest from .base import FunctionalTest
from .list_page import ListPage
# Helper fns # Helper fns
@@ -25,10 +27,12 @@ class SharingTest(FunctionalTest):
self.browser = disco_browser self.browser = disco_browser
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self.add_list_item("Send help") list_page = ListPage(self).add_list_item("Send help")
share_box = self.browser.find_element(By.CSS_SELECTOR, 'input[name="shareable"]') share_box = list_page.get_share_box()
self.assertEqual( self.assertEqual(
share_box.get_attribute("placeholder"), share_box.get_attribute("placeholder"),
"friend@example.com", "friend@example.com",
) )
list_page.share_list_with("friend@example.com")

View File

@@ -2,32 +2,36 @@ from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from .base import FunctionalTest from .base import FunctionalTest
from .list_page import ListPage
class NewVisitorTest(FunctionalTest): class NewVisitorTest(FunctionalTest):
# Test methods # Test methods
def test_can_start_a_todo_list(self): def test_can_start_a_todo_list(self):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
list_page = ListPage(self)
self.assertIn('Earthman RPG', self.browser.title) self.assertIn('Earthman RPG', self.browser.title)
header_text = self.browser.find_element(By.TAG_NAME, 'h1').text header_text = self.browser.find_element(By.TAG_NAME, 'h1').text
self.assertIn('Welcome', header_text) self.assertIn('Welcome', header_text)
inputbox = self.get_item_input_box() inputbox = list_page.get_item_input_box()
self.assertEqual(inputbox.get_attribute('placeholder'), 'Enter a to-do item') self.assertEqual(inputbox.get_attribute('placeholder'), 'Enter a to-do item')
inputbox.send_keys('Buy peacock feathers') inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER) inputbox.send_keys(Keys.ENTER)
self.wait_for_row_in_list_table('1. Buy peacock feathers') list_page.wait_for_row_in_list_table("Buy peacock feathers", 1)
self.add_list_item("Use peacock feathers to make a fly") list_page.add_list_item("Use peacock feathers to make a fly")
self.wait_for_row_in_list_table('2. Use peacock feathers to make a fly') list_page.wait_for_row_in_list_table("Use peacock feathers to make a fly", 2)
self.wait_for_row_in_list_table('1. Buy peacock feathers') list_page.wait_for_row_in_list_table("Buy peacock feathers", 1)
def test_multiple_users_can_start_lists_at_different_urls(self): def test_multiple_users_can_start_lists_at_different_urls(self):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self.add_list_item("Buy peacock feathers") list_page = ListPage(self)
list_page.add_list_item("Buy peacock feathers")
edith_dash_url = self.browser.current_url edith_dash_url = self.browser.current_url
self.assertRegex(edith_dash_url, '/apps/dashboard/.+') self.assertRegex(edith_dash_url, '/apps/dashboard/.+')
@@ -35,10 +39,11 @@ class NewVisitorTest(FunctionalTest):
self.browser.delete_all_cookies() self.browser.delete_all_cookies()
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
list_page = ListPage(self)
page_text = self.browser.find_element(By.TAG_NAME, 'body').text page_text = self.browser.find_element(By.TAG_NAME, 'body').text
self.assertNotIn('Buy peacock feathers', page_text) self.assertNotIn('Buy peacock feathers', page_text)
self.add_list_item("Buy milk") list_page.add_list_item("Buy milk")
francis_dash_url = self.browser.current_url francis_dash_url = self.browser.current_url
self.assertRegex(francis_dash_url, '/apps/dashboard/.+') self.assertRegex(francis_dash_url, '/apps/dashboard/.+')