test_binding.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. from typing import Dict, Optional, Tuple
  2. from selenium.webdriver.common.keys import Keys
  3. from nicegui import binding, ui
  4. from nicegui.testing import Screen
  5. def test_ui_select_with_tuple_as_key(screen: Screen):
  6. class Model:
  7. selection: Optional[Tuple[int, int]] = None
  8. data = Model()
  9. options = {
  10. (2, 1): 'option A',
  11. (1, 2): 'option B',
  12. }
  13. data.selection = next(iter(options))
  14. ui.select(options).bind_value(data, 'selection')
  15. screen.open('/')
  16. screen.should_not_contain('option B')
  17. element = screen.click('option A')
  18. screen.click_at_position(element, x=20, y=100)
  19. screen.wait(0.3)
  20. screen.should_contain('option B')
  21. screen.should_not_contain('option A')
  22. assert data.selection == (1, 2)
  23. def test_ui_select_with_list_of_tuples(screen: Screen):
  24. class Model:
  25. selection = None
  26. data = Model()
  27. options = [(1, 1), (2, 2), (3, 3)]
  28. data.selection = options[0]
  29. ui.select(options).bind_value(data, 'selection')
  30. screen.open('/')
  31. screen.should_not_contain('2,2')
  32. element = screen.click('1,1')
  33. screen.click_at_position(element, x=20, y=100)
  34. screen.wait(0.3)
  35. screen.should_contain('2,2')
  36. screen.should_not_contain('1,1')
  37. assert data.selection == (2, 2)
  38. def test_ui_select_with_list_of_lists(screen: Screen):
  39. class Model:
  40. selection = None
  41. data = Model()
  42. options = [[1, 1], [2, 2], [3, 3]]
  43. data.selection = options[0]
  44. ui.select(options).bind_value(data, 'selection')
  45. screen.open('/')
  46. screen.should_not_contain('2,2')
  47. element = screen.click('1,1')
  48. screen.click_at_position(element, x=20, y=100)
  49. screen.wait(0.3)
  50. screen.should_contain('2,2')
  51. screen.should_not_contain('1,1')
  52. assert data.selection == [2, 2]
  53. def test_binding_to_input(screen: Screen):
  54. class Model:
  55. text = 'one'
  56. data = Model()
  57. element = ui.input().bind_value(data, 'text')
  58. screen.open('/')
  59. screen.should_contain_input('one')
  60. screen.type(Keys.TAB)
  61. screen.type('two')
  62. screen.should_contain_input('two')
  63. screen.wait(0.1)
  64. assert data.text == 'two'
  65. data.text = 'three'
  66. screen.should_contain_input('three')
  67. element.set_value('four')
  68. screen.should_contain_input('four')
  69. assert data.text == 'four'
  70. element.value = 'five'
  71. screen.should_contain_input('five')
  72. assert data.text == 'five'
  73. def test_binding_refresh_before_page_delivery(screen: Screen):
  74. state = {'count': 0}
  75. @ui.page('/')
  76. def main_page() -> None:
  77. ui.label().bind_text_from(state, 'count')
  78. state['count'] += 1
  79. screen.open('/')
  80. screen.should_contain('1')
  81. def test_missing_target_attribute(screen: Screen):
  82. data: Dict = {}
  83. ui.label('Hello').bind_text_to(data)
  84. ui.label().bind_text_from(data, 'text', lambda text: f'{text=}')
  85. screen.open('/')
  86. screen.should_contain("text='Hello'")
  87. def test_bindable_dataclass(screen: Screen):
  88. @binding.bindable_dataclass(bindable_fields=['bindable'])
  89. class TestClass:
  90. not_bindable: str = 'not_bindable_text'
  91. bindable: str = 'bindable_text'
  92. instance = TestClass()
  93. ui.label().bind_text_from(instance, 'not_bindable')
  94. ui.label().bind_text_from(instance, 'bindable')
  95. screen.open('/')
  96. screen.should_contain('not_bindable_text')
  97. screen.should_contain('bindable_text')
  98. assert len(binding.bindings) == 2
  99. assert len(binding.active_links) == 1
  100. assert binding.active_links[0][1] == 'not_bindable'