test_favicon.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from pathlib import Path
  2. from typing import Union
  3. import pytest
  4. import requests
  5. from bs4 import BeautifulSoup
  6. from nicegui import favicon, ui
  7. from nicegui.testing import Screen
  8. DEFAULT_FAVICON_PATH = Path(__file__).parent.parent / 'nicegui' / 'static' / 'favicon.ico'
  9. LOGO_FAVICON_PATH = Path(__file__).parent.parent / 'website' / 'static' / 'logo_square.png'
  10. def assert_favicon_url_starts_with(screen: Screen, content: str):
  11. soup = BeautifulSoup(screen.selenium.page_source, 'html.parser')
  12. icon_link = soup.find('link', rel='icon')
  13. assert icon_link['href'].startswith(content)
  14. def assert_favicon(content: Union[Path, str, bytes], url_path: str = '/favicon.ico'):
  15. response = requests.get(f'http://localhost:{Screen.PORT}{url_path}', timeout=5)
  16. assert response.status_code == 200
  17. if isinstance(content, Path):
  18. assert content.read_bytes() == response.content
  19. elif isinstance(content, str):
  20. assert content == response.text
  21. elif isinstance(content, bytes):
  22. assert content == response.content
  23. else:
  24. raise TypeError(f'Unexpected type: {type(content)}')
  25. def test_default(screen: Screen):
  26. ui.label('Hello, world')
  27. screen.open('/')
  28. assert_favicon(DEFAULT_FAVICON_PATH)
  29. @pytest.mark.parametrize('emoji', ['👋', '⚔️'])
  30. def test_emoji(emoji: str, screen: Screen):
  31. ui.label('Hello, world')
  32. screen.ui_run_kwargs['favicon'] = emoji
  33. screen.open('/')
  34. assert_favicon_url_starts_with(screen, 'data:image/svg+xml')
  35. assert_favicon(favicon._char_to_svg(emoji))
  36. def test_data_url(screen: Screen):
  37. ui.label('Hello, world')
  38. icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
  39. screen.ui_run_kwargs['favicon'] = icon
  40. screen.open('/')
  41. assert_favicon_url_starts_with(screen, 'data:image/png;base64')
  42. _, bytes_ = favicon._data_url_to_bytes(icon)
  43. assert_favicon(bytes_)
  44. def test_custom_file(screen: Screen):
  45. ui.label('Hello, world')
  46. screen.ui_run_kwargs['favicon'] = LOGO_FAVICON_PATH
  47. screen.open('/')
  48. assert_favicon_url_starts_with(screen, '/favicon.ico')
  49. assert_favicon(screen.ui_run_kwargs['favicon'])
  50. def test_page_specific_icon(screen: Screen):
  51. @ui.page('/subpage', favicon=LOGO_FAVICON_PATH)
  52. def sub():
  53. ui.label('Subpage')
  54. ui.label('Main')
  55. screen.open('/subpage')
  56. assert_favicon(LOGO_FAVICON_PATH, url_path='/subpage/favicon.ico')
  57. screen.open('/')
  58. def test_page_specific_emoji(screen: Screen):
  59. @ui.page('/subpage', favicon='👋')
  60. def sub():
  61. ui.label('Subpage')
  62. ui.label('Main')
  63. screen.open('/subpage')
  64. assert_favicon_url_starts_with(screen, 'data:image/svg+xml')
  65. screen.open('/')
  66. assert_favicon(DEFAULT_FAVICON_PATH)