|
| 1 | +import os |
1 | 2 | from http import HTTPStatus |
2 | 3 | from io import StringIO |
3 | 4 |
|
4 | 5 | from django.conf import settings |
| 6 | +from django.contrib.staticfiles.testing import StaticLiveServerTestCase |
5 | 7 | from django.core.management import call_command |
6 | 8 | from django.test import TestCase |
7 | 9 | from django.urls import NoReverseMatch, get_resolver |
8 | 10 | from django.utils.translation import activate, gettext as _ |
9 | 11 | from django_hosts.resolvers import reverse |
| 12 | +from playwright.sync_api import expect, sync_playwright |
10 | 13 |
|
11 | 14 | from docs.models import DocumentRelease, Release |
12 | 15 |
|
@@ -211,3 +214,70 @@ def test_single_h1_per_page(self): |
211 | 214 | response = self.client.get(url) |
212 | 215 | self.assertEqual(response.status_code, 200) |
213 | 216 | self.assertContains(response, "<h1", count=1) |
| 217 | + |
| 218 | + |
| 219 | +class EndToEndTests(ReleaseMixin, StaticLiveServerTestCase): |
| 220 | + @classmethod |
| 221 | + def setUpClass(cls): |
| 222 | + os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" |
| 223 | + super().setUpClass() |
| 224 | + cls.playwright = sync_playwright().start() |
| 225 | + cls.browser = cls.playwright.chromium.launch() |
| 226 | + |
| 227 | + @classmethod |
| 228 | + def tearDownClass(cls): |
| 229 | + super().tearDownClass() |
| 230 | + cls.browser.close() |
| 231 | + cls.playwright.stop() |
| 232 | + |
| 233 | + def setUp(self): |
| 234 | + self.setUpTestData() |
| 235 | + self.mac_user_agent = "Mozilla/5.0 (Macintosh) AppleWebKit" |
| 236 | + self.windows_user_agent = "Mozilla/5.0 (Windows NT 10.0)" |
| 237 | + self.mobile_linux_user_agent = "Mozilla/5.0 (Linux; Android 10; Mobile)" |
| 238 | + |
| 239 | + def test_search_ctrl_k_hotkey_desktop(self): |
| 240 | + page = self.browser.new_page(user_agent=self.windows_user_agent) |
| 241 | + page.goto(self.live_server_url) |
| 242 | + |
| 243 | + mobile_search_bar = page.locator("#id_mobile-q") |
| 244 | + desktop_search_bar = page.locator("#id_desktop-q") |
| 245 | + self.assertFalse(mobile_search_bar.is_visible()) |
| 246 | + self.assertTrue(desktop_search_bar.is_visible()) |
| 247 | + expect(desktop_search_bar).to_have_attribute("placeholder", "Search (Ctrl+K)") |
| 248 | + is_focused = page.evaluate("document.activeElement.id === 'id_desktop-q'") |
| 249 | + self.assertFalse(is_focused) |
| 250 | + |
| 251 | + page.keyboard.press("Control+KeyK") |
| 252 | + is_focused = page.evaluate("document.activeElement.id === 'id_desktop-q'") |
| 253 | + self.assertTrue(is_focused) |
| 254 | + page.close() |
| 255 | + |
| 256 | + def test_search_ctrl_k_hotkey_mobile(self): |
| 257 | + page = self.browser.new_page( |
| 258 | + user_agent=self.mobile_linux_user_agent, |
| 259 | + viewport={"width": 375, "height": 812}, |
| 260 | + ) |
| 261 | + page.goto(self.live_server_url) |
| 262 | + |
| 263 | + mobile_search_bar = page.locator("#id_mobile-q") |
| 264 | + desktop_search_bar = page.locator("#id_desktop-q") |
| 265 | + self.assertTrue(mobile_search_bar.is_visible()) |
| 266 | + expect(mobile_search_bar).to_have_attribute("placeholder", "Search (Ctrl+K)") |
| 267 | + self.assertFalse(desktop_search_bar.is_visible()) |
| 268 | + is_focused = page.evaluate("document.activeElement.id === 'id_mobile-q'") |
| 269 | + self.assertFalse(is_focused) |
| 270 | + |
| 271 | + page.keyboard.press("Control+KeyK") |
| 272 | + is_focused = page.evaluate("document.activeElement.id === 'id_mobile-q'") |
| 273 | + self.assertTrue(is_focused) |
| 274 | + page.close() |
| 275 | + |
| 276 | + def test_search_placeholder_mac_mode(self): |
| 277 | + page = self.browser.new_page(user_agent=self.mac_user_agent) |
| 278 | + page.goto(self.live_server_url) |
| 279 | + |
| 280 | + desktop_search_bar = page.locator("#id_desktop-q") |
| 281 | + expect(desktop_search_bar).to_have_attribute("placeholder", "Search (⌘\u200aK)") |
| 282 | + |
| 283 | + page.close() |
0 commit comments