conftest.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import importlib
  2. import os
  3. import shutil
  4. from pathlib import Path
  5. from typing import Dict, Generator
  6. import icecream
  7. import pytest
  8. from selenium import webdriver
  9. from selenium.webdriver.chrome.service import Service
  10. from nicegui import Client, binding, globals # pylint: disable=redefined-builtin
  11. from nicegui.elements import plotly, pyplot
  12. from nicegui.page import page
  13. from .screen import Screen
  14. DOWNLOAD_DIR = Path(__file__).parent / 'download'
  15. icecream.install()
  16. @pytest.fixture
  17. def chrome_options(chrome_options: webdriver.ChromeOptions) -> webdriver.ChromeOptions:
  18. chrome_options.add_argument('disable-dev-shm-using')
  19. chrome_options.add_argument('no-sandbox')
  20. chrome_options.add_argument('headless')
  21. chrome_options.add_argument('disable-gpu')
  22. chrome_options.add_argument('window-size=600x600')
  23. chrome_options.add_experimental_option('prefs', {
  24. "download.default_directory": str(DOWNLOAD_DIR),
  25. "download.prompt_for_download": False, # To auto download the file
  26. "download.directory_upgrade": True,
  27. })
  28. if 'CHROME_BINARY_LOCATION' in os.environ:
  29. chrome_options.binary_location = os.environ['CHROME_BINARY_LOCATION']
  30. return chrome_options
  31. @pytest.fixture
  32. def capabilities(capabilities: Dict) -> Dict:
  33. capabilities['goog:loggingPrefs'] = {'browser': 'ALL'}
  34. return capabilities
  35. @pytest.fixture(autouse=True)
  36. def reset_globals() -> Generator[None, None, None]:
  37. for path in {'/'}.union(globals.page_routes.values()):
  38. globals.app.remove_route(path)
  39. globals.app.openapi_schema = None
  40. globals.app.middleware_stack = None
  41. globals.app.user_middleware.clear()
  42. # NOTE favicon routes must be removed separately because they are not "pages"
  43. for route in globals.app.routes:
  44. if route.path.endswith('/favicon.ico'):
  45. globals.app.routes.remove(route)
  46. importlib.reload(globals)
  47. # repopulate globals.optional_features
  48. importlib.reload(plotly)
  49. importlib.reload(pyplot)
  50. globals.app.storage.clear()
  51. globals.index_client = Client(page('/'), shared=True).__enter__()
  52. globals.app.get('/')(globals.index_client.build_response)
  53. binding.reset()
  54. @pytest.fixture(scope='session', autouse=True)
  55. def remove_all_screenshots() -> None:
  56. if os.path.exists(Screen.SCREENSHOT_DIR):
  57. for name in os.listdir(Screen.SCREENSHOT_DIR):
  58. os.remove(os.path.join(Screen.SCREENSHOT_DIR, name))
  59. @pytest.fixture(scope='function')
  60. def driver(chrome_options: webdriver.ChromeOptions) -> webdriver.Chrome:
  61. s = Service()
  62. driver_ = webdriver.Chrome(service=s, options=chrome_options)
  63. driver_.implicitly_wait(Screen.IMPLICIT_WAIT)
  64. driver_.set_page_load_timeout(4)
  65. yield driver_
  66. driver_.quit()
  67. @pytest.fixture
  68. def screen(driver: webdriver.Chrome, request: pytest.FixtureRequest, caplog: pytest.LogCaptureFixture) \
  69. -> Generator[Screen, None, None]:
  70. screen_ = Screen(driver, caplog)
  71. yield screen_
  72. if screen_.is_open:
  73. screen_.shot(request.node.name)
  74. logs = screen_.caplog.get_records('call')
  75. screen_.stop_server()
  76. if DOWNLOAD_DIR.exists():
  77. shutil.rmtree(DOWNLOAD_DIR)
  78. if logs:
  79. pytest.fail('There were unexpected logs. See "Captured log call" below.', pytrace=False)