test_input.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import pytest
  2. from selenium.webdriver.common.by import By
  3. from selenium.webdriver.common.keys import Keys
  4. from nicegui import ui
  5. from nicegui.testing import Screen
  6. def test_input(screen: Screen):
  7. ui.input('Your name', value='John Doe')
  8. screen.open('/')
  9. screen.should_contain('Your name')
  10. element = screen.selenium.find_element(By.XPATH, '//*[@aria-label="Your name"]')
  11. assert element.get_attribute('type') == 'text'
  12. assert element.get_attribute('value') == 'John Doe'
  13. element.send_keys(' Jr.')
  14. assert element.get_attribute('value') == 'John Doe Jr.'
  15. def test_password(screen: Screen):
  16. ui.input('Your password', value='123456', password=True)
  17. screen.open('/')
  18. screen.should_contain('Your password')
  19. element = screen.selenium.find_element(By.XPATH, '//*[@aria-label="Your password"]')
  20. assert element.get_attribute('type') == 'password'
  21. assert element.get_attribute('value') == '123456'
  22. element.send_keys('789')
  23. screen.wait(0.5)
  24. assert element.get_attribute('value') == '123456789'
  25. def test_toggle_button(screen: Screen):
  26. ui.input('Your password', value='123456', password=True, password_toggle_button=True)
  27. screen.open('/')
  28. screen.should_contain('Your password')
  29. screen.should_contain('visibility_off')
  30. element = screen.selenium.find_element(By.XPATH, '//*[@aria-label="Your password"]')
  31. assert element.get_attribute('type') == 'password'
  32. assert element.get_attribute('value') == '123456'
  33. screen.click('visibility_off')
  34. screen.wait(0.5)
  35. assert element.get_attribute('type') == 'text'
  36. screen.click('visibility')
  37. screen.wait(0.5)
  38. assert element.get_attribute('type') == 'password'
  39. @pytest.mark.parametrize('use_callable', [False, True])
  40. def test_input_validation(use_callable: bool, screen: Screen):
  41. if use_callable:
  42. input_ = ui.input('Name', validation=lambda value: 'Too short' if len(value) < 5 else None)
  43. else:
  44. input_ = ui.input('Name', validation={'Too short': lambda value: len(value) >= 5})
  45. screen.open('/')
  46. screen.should_contain('Name')
  47. element = screen.selenium.find_element(By.XPATH, '//*[@aria-label="Name"]')
  48. element.send_keys('John')
  49. screen.should_contain('Too short')
  50. assert input_.error == 'Too short'
  51. assert not input_.validate()
  52. element.send_keys(' Doe')
  53. screen.wait(0.5)
  54. screen.should_not_contain('Too short')
  55. assert input_.error is None
  56. assert input_.validate()
  57. def test_input_with_multi_word_error_message(screen: Screen):
  58. input_ = ui.input(label='some input')
  59. ui.button('set error', on_click=lambda: input_.props('error error-message="Some multi word error message"'))
  60. screen.open('/')
  61. screen.should_not_contain('Some multi word error message')
  62. screen.click('set error')
  63. screen.should_contain('Some multi word error message')
  64. def test_autocompletion(screen: Screen):
  65. input_ = ui.input('Input', autocomplete=['foo', 'bar', 'baz'])
  66. screen.open('/')
  67. element = screen.selenium.find_element(By.XPATH, '//*[@aria-label="Input"]')
  68. element.send_keys('f')
  69. screen.should_contain('oo')
  70. element.send_keys('l')
  71. screen.wait(0.5)
  72. screen.should_not_contain('oo')
  73. element.send_keys(Keys.BACKSPACE)
  74. screen.should_contain('oo')
  75. element.send_keys(Keys.TAB)
  76. screen.wait(0.2)
  77. assert element.get_attribute('value') == 'foo'
  78. assert input_.value == 'foo'
  79. element.send_keys(Keys.BACKSPACE)
  80. element.send_keys(Keys.BACKSPACE)
  81. element.send_keys('x')
  82. element.send_keys(Keys.TAB)
  83. screen.wait(0.5)
  84. assert element.get_attribute('value') == 'fx'
  85. assert input_.value == 'fx'
  86. input_.set_autocomplete(['one', 'two'])
  87. element.send_keys(Keys.BACKSPACE)
  88. element.send_keys(Keys.BACKSPACE)
  89. element.send_keys('o')
  90. screen.should_contain('ne')
  91. def test_clearable_input(screen: Screen):
  92. input_ = ui.input(value='foo').props('clearable')
  93. ui.label().bind_text_from(input_, 'value', lambda value: f'value: {value}')
  94. screen.open('/')
  95. screen.should_contain('value: foo')
  96. screen.click('cancel')
  97. screen.should_contain('value: None')
  98. def test_update_input(screen: Screen):
  99. input_ = ui.input('Name', value='Pete')
  100. screen.open('/')
  101. element = screen.selenium.find_element(By.XPATH, '//*[@aria-label="Name"]')
  102. assert element.get_attribute('value') == 'Pete'
  103. element.send_keys('r')
  104. screen.wait(0.5)
  105. assert element.get_attribute('value') == 'Peter'
  106. input_.value = 'Pete'
  107. screen.wait(0.5)
  108. assert element.get_attribute('value') == 'Pete'
  109. def test_switching_focus(screen: Screen):
  110. input1 = ui.input()
  111. input2 = ui.input()
  112. ui.button('focus 1', on_click=lambda: input1.run_method('focus'))
  113. ui.button('focus 2', on_click=lambda: input2.run_method('focus'))
  114. screen.open('/')
  115. elements = screen.selenium.find_elements(By.XPATH, '//input')
  116. assert len(elements) == 2
  117. screen.click('focus 1')
  118. screen.wait(0.3)
  119. assert elements[0] == screen.selenium.switch_to.active_element
  120. screen.click('focus 2')
  121. screen.wait(0.3)
  122. assert elements[1] == screen.selenium.switch_to.active_element