diff --git a/functional_tests/base.py b/functional_tests/base.py new file mode 100644 index 0000000000000000000000000000000000000000..624cfd34391ca9a4f047e1437ba8ae97e66472d5 --- /dev/null +++ b/functional_tests/base.py @@ -0,0 +1,37 @@ +from django.contrib.staticfiles.testing import StaticLiveServerTestCase +from selenium import webdriver +from selenium.common.exceptions import WebDriverException +import time + +MAX_WAIT = 10 + + +class FunctionalTest(StaticLiveServerTestCase): + def setUp(self): + self.browser = webdriver.Chrome() + + def tearDown(self): + self.browser.quit() + + def wait_for_row_in_list_table(self, row_text): + start_time = time.time() + while True: + try: + table = self.browser.find_element_by_id('id_list_table') + rows = table.find_elements_by_tag_name('tr') + self.assertIn(row_text, [row.text for row in rows]) + return + except (AssertionError, WebDriverException) as e: + if time.time() - start_time > MAX_WAIT: + raise e + time.sleep(0.5) + + def wait_for(self, fn): + start_time = time.time() + while True: + try: + return fn() + except (AssertionError, WebDriverException) as e: + if time.time() - start_time > MAX_WAIT: + raise e + time.sleep(0.5) diff --git a/functional_tests/test_layout_and_styling.py b/functional_tests/test_layout_and_styling.py new file mode 100644 index 0000000000000000000000000000000000000000..135aa45a8bbd1e06f3669fdff52f84c5792dbe69 --- /dev/null +++ b/functional_tests/test_layout_and_styling.py @@ -0,0 +1,28 @@ +from selenium.webdriver.common.keys import Keys +from .base import FunctionalTest + + +class LayoutAndStylingTest(FunctionalTest): + def test_layout_and_styling(self): + # Edith goes to the home page + self.browser.get(self.live_server_url) + self.browser.set_window_size(1024, 768) + # She notices the input box is nicely centered + inputbox = self.browser.find_element_by_id('id_new_item') + self.assertAlmostEqual( + inputbox.location['x'] + inputbox.size['width'] / 2, + 512, + delta=10 + ) + + # She starts a new list and sees the input is nicely + # centered there too + inputbox.send_keys('testing') + inputbox.send_keys(Keys.ENTER) + self.wait_for_row_in_list_table('1: testing') + inputbox = self.browser.find_element_by_id('id_new_item') + self.assertAlmostEqual( + inputbox.location['x'] + inputbox.size['width'] / 2, + 512, + delta=10 + ) diff --git a/functional_tests/test_list_item_validation.py b/functional_tests/test_list_item_validation.py new file mode 100644 index 0000000000000000000000000000000000000000..65aa7d3d7a578cbc7d2f015adcbe93876025b114 --- /dev/null +++ b/functional_tests/test_list_item_validation.py @@ -0,0 +1,38 @@ +from selenium.webdriver.common.keys import Keys +from unittest import skip +from .base import FunctionalTest + + +class ItemValidationTest(FunctionalTest): + + def test_cannot_add_empty_list_items(self): + # Edith goes to the home page and accidentally tries to submit + # an empty list item. She hits Enter on the empty input box + self.browser.get(self.live_server_url) + self.browser.find_element_by_id('id_new_item').send_keys(Keys.ENTER) + # The home page refreshes, and there is an error message saying + # that list items cannot be blank + self.wait_for(lambda: self.assertEqual( + self.browser.find_element_by_css_selector('.has-error').text, + "You can't have an empty list item" + )) + + # She tries again with some text for the item, which now works + self.browser.find_element_by_id('id_new_item').send_keys('Buy milk') + self.browser.find_element_by_id('id_new_item').send_keys(Keys.ENTER) + self.wait_for_row_in_list_table('1: Buy milk') + + # Perversely, she now decides to submit a second blank list item + self.browser.find_element_by_id('id_new_item').send_keys(Keys.ENTER) + + # She receives a similar warning on the list page + self.wait_for(lambda: self.assertEqual( + self.browser.find_element_by_css_selector('.has-error').text, + "You can't have an empty list item" + )) + + # And she can correct it by filling some text in + self.browser.find_element_by_id('id_new_item').send_keys('Make tea') + self.browser.find_element_by_id('id_new_item').send_keys(Keys.ENTER) + self.wait_for_row_in_list_table('1: Buy milk') + self.wait_for_row_in_list_table('2: Make tea') diff --git a/functional_tests/tests.py b/functional_tests/test_simple_list_creation.py similarity index 58% rename from functional_tests/tests.py rename to functional_tests/test_simple_list_creation.py index d82578259a92ca17db3f5fc088222eb3d0106f88..3d9de52003394c17a772ccf8c630c667de2b908f 100644 --- a/functional_tests/tests.py +++ b/functional_tests/test_simple_list_creation.py @@ -1,33 +1,9 @@ -from selenium import webdriver -from selenium.common.exceptions import WebDriverException +from .base import FunctionalTest from selenium.webdriver.common.keys import Keys -from django.contrib.staticfiles.testing import StaticLiveServerTestCase import time -import os -MAX_WAIT = 10 - - -class NewVisitorTest(StaticLiveServerTestCase): - def setUp(self): - self.browser = webdriver.Chrome() - - def tearDown(self): - self.browser.quit() - - def wait_for_row_in_list_table(self, row_text): - start_time = time.time() - while True: - try: - table = self.browser.find_element_by_id('id_list_table') - rows = table.find_elements_by_tag_name('tr') - self.assertIn(row_text, [row.text for row in rows]) - return - except (AssertionError, WebDriverException) as e: - if time.time() - start_time > MAX_WAIT: - raise e - time.sleep(0.5) +class NewVisitorTest(FunctionalTest): def test_can_start_a_list_and_retrieve_it_later(self): # Edith has heard about a cool new online to-do app. She goes # to check out its homepage @@ -97,32 +73,3 @@ class NewVisitorTest(StaticLiveServerTestCase): comment.text, 'oh tidak' ) - - # Edith wonders whether the site will remember her list. Then she sees - # that the site has generated a unique URL for her -- there is some - # explanatory text to that effect. - self.fail('Finish the test!') - - def test_layout_and_styling(self): - # Edith goes to the home page - self.browser.get(self.live_server_url) - self.browser.set_window_size(1024, 768) - # She notices the input box is nicely centered - inputbox = self.browser.find_element_by_id('id_new_item') - self.assertAlmostEqual( - inputbox.location['x'] + inputbox.size['width'] / 2, - 512, - delta=10 - ) - - # She starts a new list and sees the input is nicely - # centered there too - inputbox.send_keys('testing') - inputbox.send_keys(Keys.ENTER) - self.wait_for_row_in_list_table('1: testing') - inputbox = self.browser.find_element_by_id('id_new_item') - self.assertAlmostEqual( - inputbox.location['x'] + inputbox.size['width'] / 2, - 512, - delta=10 - ) diff --git a/latihan2/tests/__init__.py b/latihan2/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/latihan2/tests/test_model.py b/latihan2/tests/test_model.py new file mode 100644 index 0000000000000000000000000000000000000000..efb1c9b1afa78bb6bcbe32c14eb809b2331ca582 --- /dev/null +++ b/latihan2/tests/test_model.py @@ -0,0 +1,18 @@ +from django.test import TestCase +from latihan2.models import Item + + +class ItemModelTest(TestCase): + def test_saving_and_retrieving_items(self): + first_item = Item() + first_item.text = 'The first (ever) list item' + first_item.save() + second_item = Item() + second_item.text = 'Item the second' + second_item.save() + saved_items = Item.objects.all() + self.assertEqual(saved_items.count(), 2) + first_saved_item = saved_items[0] + second_saved_item = saved_items[1] + self.assertEqual(first_saved_item.text, 'The first (ever) list item') + self.assertEqual(second_saved_item.text, 'Item the second') diff --git a/latihan2/tests.py b/latihan2/tests/test_views.py similarity index 80% rename from latihan2/tests.py rename to latihan2/tests/test_views.py index 887fb4fd2bec37deb464a0092dcb8964352fac47..b16d6d188abb9a889db00b8d3051c2985fe82375 100644 --- a/latihan2/tests.py +++ b/latihan2/tests/test_views.py @@ -1,6 +1,5 @@ from django.urls import resolve from django.test import TestCase -from django.http import HttpRequest from latihan2.views import home_page from latihan2.models import Item @@ -67,19 +66,3 @@ class HomePageTest(TestCase): response = self.client.get('/') self.assertIn('oh tidak', response.content.decode()) - - -class ItemModelTest(TestCase): - def test_saving_and_retrieving_items(self): - first_item = Item() - first_item.text = 'The first (ever) list item' - first_item.save() - second_item = Item() - second_item.text = 'Item the second' - second_item.save() - saved_items = Item.objects.all() - self.assertEqual(saved_items.count(), 2) - first_saved_item = saved_items[0] - second_saved_item = saved_items[1] - self.assertEqual(first_saved_item.text, 'The first (ever) list item') - self.assertEqual(second_saved_item.text, 'Item the second')