1
0

general_fixtures.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import importlib
  2. from typing import Generator, List, Type
  3. import pytest
  4. from starlette.routing import Route
  5. import nicegui.storage
  6. from nicegui import Client, app, binding, core, run, ui
  7. from nicegui.page import page
  8. # pylint: disable=redefined-outer-name
  9. def pytest_configure(config: pytest.Config) -> None:
  10. """Add the "module_under_test" marker to the pytest configuration."""
  11. config.addinivalue_line('markers',
  12. 'module_under_test(module): specify the module under test which then gets automatically reloaded.')
  13. @pytest.fixture
  14. def nicegui_reset_globals() -> Generator[None, None, None]:
  15. """Reset the global state of the NiceGUI package."""
  16. for route in app.routes:
  17. if isinstance(route, Route) and route.path.startswith('/_nicegui/auto/static/'):
  18. app.remove_route(route.path)
  19. for path in {'/'}.union(Client.page_routes.values()):
  20. app.remove_route(path)
  21. app.openapi_schema = None
  22. app.middleware_stack = None
  23. app.user_middleware.clear()
  24. app.urls.clear()
  25. core.air = None
  26. # NOTE favicon routes must be removed separately because they are not "pages"
  27. for route in app.routes:
  28. if isinstance(route, Route) and route.path.endswith('/favicon.ico'):
  29. app.routes.remove(route)
  30. importlib.reload(core)
  31. importlib.reload(run)
  32. element_classes: List[Type[ui.element]] = [ui.element]
  33. while element_classes:
  34. parent = element_classes.pop()
  35. for cls in parent.__subclasses__():
  36. cls._default_props = {} # pylint: disable=protected-access
  37. cls._default_style = {} # pylint: disable=protected-access
  38. cls._default_classes = [] # pylint: disable=protected-access
  39. element_classes.append(cls)
  40. Client.instances.clear()
  41. Client.page_routes.clear()
  42. app.reset()
  43. Client.auto_index_client = Client(page('/'), request=None).__enter__() # pylint: disable=unnecessary-dunder-call
  44. # NOTE we need to re-add the auto index route because we removed all routes above
  45. app.get('/')(Client.auto_index_client.build_response)
  46. binding.reset()
  47. yield
  48. def prepare_simulation(request: pytest.FixtureRequest) -> None:
  49. """Prepare a simulation to be started.
  50. By using the "module_under_test" marker you can specify the main entry point of the app.
  51. """
  52. marker = request.node.get_closest_marker('module_under_test')
  53. if marker is not None:
  54. with Client.auto_index_client:
  55. importlib.reload(marker.args[0])
  56. core.app.config.add_run_config(
  57. reload=False,
  58. title='Test App',
  59. viewport='',
  60. favicon=None,
  61. dark=False,
  62. language='en-US',
  63. binding_refresh_interval=0.1,
  64. reconnect_timeout=3.0,
  65. tailwind=True,
  66. prod_js=True,
  67. show_welcome_message=False,
  68. )
  69. nicegui.storage.set_storage_secret('simulated secret')