test_var_operations.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. """Integration tests for var operations."""
  2. from typing import Generator
  3. import pytest
  4. from selenium.webdriver.common.by import By
  5. from reflex.testing import AppHarness
  6. # pyright: reportOptionalMemberAccess=false, reportGeneralTypeIssues=false, reportUnknownMemberType=false
  7. def VarOperations():
  8. """App with var operations."""
  9. import reflex as rx
  10. class VarOperationState(rx.State):
  11. int_var1: int = 10
  12. int_var2: int = 5
  13. int_var3: int = 7
  14. float_var1: float = 10.5
  15. float_var2: float = 5.5
  16. list1: list = [1, 2]
  17. list2: list = [3, 4]
  18. list3: list = ["first", "second", "third"]
  19. str_var1: str = "first"
  20. str_var2: str = "second"
  21. str_var3: str = "ThIrD"
  22. str_var4: str = "a long string"
  23. dict1: dict = {1: 2}
  24. dict2: dict = {3: 4}
  25. @rx.var
  26. def token(self) -> str:
  27. return self.get_token()
  28. app = rx.App(state=VarOperationState)
  29. @app.add_page
  30. def index():
  31. return rx.vstack(
  32. rx.input(id="token", value=VarOperationState.token, is_read_only=True),
  33. # INT INT
  34. rx.text(
  35. VarOperationState.int_var1 + VarOperationState.int_var2,
  36. id="int_add_int",
  37. ),
  38. rx.text(
  39. VarOperationState.int_var1 * VarOperationState.int_var2,
  40. id="int_mult_int",
  41. ),
  42. rx.text(
  43. VarOperationState.int_var1 - VarOperationState.int_var2,
  44. id="int_sub_int",
  45. ),
  46. rx.text(
  47. VarOperationState.int_var1**VarOperationState.int_var2,
  48. id="int_exp_int",
  49. ),
  50. rx.text(
  51. VarOperationState.int_var1 / VarOperationState.int_var2,
  52. id="int_div_int",
  53. ),
  54. rx.text(
  55. VarOperationState.int_var1 // VarOperationState.int_var3,
  56. id="int_floor_int",
  57. ),
  58. rx.text(
  59. VarOperationState.int_var1 % VarOperationState.int_var2,
  60. id="int_mod_int",
  61. ),
  62. rx.text(
  63. VarOperationState.int_var1 | VarOperationState.int_var2,
  64. id="int_or_int",
  65. ),
  66. rx.text(
  67. (VarOperationState.int_var1 > VarOperationState.int_var2).to_string(),
  68. id="int_gt_int",
  69. ),
  70. rx.text(
  71. (VarOperationState.int_var1 < VarOperationState.int_var2).to_string(),
  72. id="int_lt_int",
  73. ),
  74. rx.text(
  75. (VarOperationState.int_var1 >= VarOperationState.int_var2).to_string(),
  76. id="int_gte_int",
  77. ),
  78. rx.text(
  79. (VarOperationState.int_var1 <= VarOperationState.int_var2).to_string(),
  80. id="int_lte_int",
  81. ),
  82. rx.text(
  83. VarOperationState.int_var1 & VarOperationState.int_var2,
  84. id="int_and_int",
  85. ),
  86. rx.text(
  87. (VarOperationState.int_var1 | VarOperationState.int_var2).to_string(),
  88. id="int_or_int",
  89. ),
  90. rx.text(
  91. (VarOperationState.int_var1 == VarOperationState.int_var2).to_string(),
  92. id="int_eq_int",
  93. ),
  94. rx.text(
  95. (VarOperationState.int_var1 != VarOperationState.int_var2).to_string(),
  96. id="int_neq_int",
  97. ),
  98. # INT FLOAT OR FLOAT INT
  99. rx.text(
  100. VarOperationState.float_var1 + VarOperationState.int_var2,
  101. id="float_add_int",
  102. ),
  103. rx.text(
  104. VarOperationState.float_var1 * VarOperationState.int_var2,
  105. id="float_mult_int",
  106. ),
  107. rx.text(
  108. VarOperationState.float_var1 - VarOperationState.int_var2,
  109. id="float_sub_int",
  110. ),
  111. rx.text(
  112. VarOperationState.float_var1**VarOperationState.int_var2,
  113. id="float_exp_int",
  114. ),
  115. rx.text(
  116. VarOperationState.float_var1 / VarOperationState.int_var2,
  117. id="float_div_int",
  118. ),
  119. rx.text(
  120. VarOperationState.float_var1 // VarOperationState.int_var3,
  121. id="float_floor_int",
  122. ),
  123. rx.text(
  124. VarOperationState.float_var1 % VarOperationState.int_var2,
  125. id="float_mod_int",
  126. ),
  127. rx.text(
  128. (VarOperationState.float_var1 > VarOperationState.int_var2).to_string(),
  129. id="float_gt_int",
  130. ),
  131. rx.text(
  132. (VarOperationState.float_var1 < VarOperationState.int_var2).to_string(),
  133. id="float_lt_int",
  134. ),
  135. rx.text(
  136. (
  137. VarOperationState.float_var1 >= VarOperationState.int_var2
  138. ).to_string(),
  139. id="float_gte_int",
  140. ),
  141. rx.text(
  142. (
  143. VarOperationState.float_var1 <= VarOperationState.int_var2
  144. ).to_string(),
  145. id="float_lte_int",
  146. ),
  147. rx.text(
  148. (
  149. VarOperationState.float_var1 == VarOperationState.int_var2
  150. ).to_string(),
  151. id="float_eq_int",
  152. ),
  153. rx.text(
  154. (
  155. VarOperationState.float_var1 != VarOperationState.int_var2
  156. ).to_string(),
  157. id="float_neq_int",
  158. ),
  159. rx.text(
  160. (VarOperationState.float_var1 & VarOperationState.int_var2).to_string(),
  161. id="float_and_int",
  162. ),
  163. rx.text(
  164. (VarOperationState.float_var1 | VarOperationState.int_var2).to_string(),
  165. id="float_or_int",
  166. ),
  167. # INT, DICT
  168. rx.text(
  169. (VarOperationState.int_var1 | VarOperationState.dict1).to_string(),
  170. id="int_or_dict",
  171. ),
  172. rx.text(
  173. (VarOperationState.int_var1 & VarOperationState.dict1).to_string(),
  174. id="int_and_dict",
  175. ),
  176. rx.text(
  177. (VarOperationState.int_var1 == VarOperationState.dict1).to_string(),
  178. id="int_eq_dict",
  179. ),
  180. rx.text(
  181. (VarOperationState.int_var1 != VarOperationState.dict1).to_string(),
  182. id="int_neq_dict",
  183. ),
  184. # FLOAT FLOAT
  185. rx.text(
  186. VarOperationState.float_var1 + VarOperationState.float_var2,
  187. id="float_add_float",
  188. ),
  189. rx.text(
  190. VarOperationState.float_var1 * VarOperationState.float_var2,
  191. id="float_mult_float",
  192. ),
  193. rx.text(
  194. VarOperationState.float_var1 - VarOperationState.float_var2,
  195. id="float_sub_float",
  196. ),
  197. rx.text(
  198. VarOperationState.float_var1**VarOperationState.float_var2,
  199. id="float_exp_float",
  200. ),
  201. rx.text(
  202. VarOperationState.float_var1 / VarOperationState.float_var2,
  203. id="float_div_float",
  204. ),
  205. rx.text(
  206. VarOperationState.float_var1 // VarOperationState.float_var2,
  207. id="float_floor_float",
  208. ),
  209. rx.text(
  210. VarOperationState.float_var1 % VarOperationState.float_var2,
  211. id="float_mod_float",
  212. ),
  213. rx.text(
  214. (
  215. VarOperationState.float_var1 > VarOperationState.float_var2
  216. ).to_string(),
  217. id="float_gt_float",
  218. ),
  219. rx.text(
  220. (
  221. VarOperationState.float_var1 < VarOperationState.float_var2
  222. ).to_string(),
  223. id="float_lt_float",
  224. ),
  225. rx.text(
  226. (
  227. VarOperationState.float_var1 >= VarOperationState.float_var2
  228. ).to_string(),
  229. id="float_gte_float",
  230. ),
  231. rx.text(
  232. (
  233. VarOperationState.float_var1 <= VarOperationState.float_var2
  234. ).to_string(),
  235. id="float_lte_float",
  236. ),
  237. rx.text(
  238. (
  239. VarOperationState.float_var1 == VarOperationState.float_var2
  240. ).to_string(),
  241. id="float_eq_float",
  242. ),
  243. rx.text(
  244. (
  245. VarOperationState.float_var1 != VarOperationState.float_var2
  246. ).to_string(),
  247. id="float_neq_float",
  248. ),
  249. rx.text(
  250. (
  251. VarOperationState.float_var1 & VarOperationState.float_var2
  252. ).to_string(),
  253. id="float_and_float",
  254. ),
  255. rx.text(
  256. (
  257. VarOperationState.float_var1 | VarOperationState.float_var2
  258. ).to_string(),
  259. id="float_or_float",
  260. ),
  261. # FLOAT STR
  262. rx.text(
  263. VarOperationState.float_var1 | VarOperationState.str_var1,
  264. id="float_or_str",
  265. ),
  266. rx.text(
  267. VarOperationState.float_var1 & VarOperationState.str_var1,
  268. id="float_and_str",
  269. ),
  270. rx.text(
  271. (
  272. VarOperationState.float_var1 == VarOperationState.str_var1
  273. ).to_string(),
  274. id="float_eq_str",
  275. ),
  276. rx.text(
  277. (
  278. VarOperationState.float_var1 != VarOperationState.str_var1
  279. ).to_string(),
  280. id="float_neq_str",
  281. ),
  282. # FLOAT LIST
  283. rx.text(
  284. (VarOperationState.float_var1 | VarOperationState.list1).to_string(),
  285. id="float_or_list",
  286. ),
  287. rx.text(
  288. (VarOperationState.float_var1 & VarOperationState.list1).to_string(),
  289. id="float_and_list",
  290. ),
  291. rx.text(
  292. (VarOperationState.float_var1 == VarOperationState.list1).to_string(),
  293. id="float_eq_list",
  294. ),
  295. rx.text(
  296. (VarOperationState.float_var1 != VarOperationState.list1).to_string(),
  297. id="float_neq_list",
  298. ),
  299. # FLOAT DICT
  300. rx.text(
  301. (VarOperationState.float_var1 | VarOperationState.dict1).to_string(),
  302. id="float_or_dict",
  303. ),
  304. rx.text(
  305. (VarOperationState.float_var1 & VarOperationState.dict1).to_string(),
  306. id="float_and_dict",
  307. ),
  308. rx.text(
  309. (VarOperationState.float_var1 == VarOperationState.dict1).to_string(),
  310. id="float_eq_dict",
  311. ),
  312. rx.text(
  313. (VarOperationState.float_var1 != VarOperationState.dict1).to_string(),
  314. id="float_neq_dict",
  315. ),
  316. # STR STR
  317. rx.text(
  318. VarOperationState.str_var1 + VarOperationState.str_var2,
  319. id="str_add_str",
  320. ),
  321. rx.text(
  322. (VarOperationState.str_var1 > VarOperationState.str_var2).to_string(),
  323. id="str_gt_str",
  324. ),
  325. rx.text(
  326. (VarOperationState.str_var1 < VarOperationState.str_var2).to_string(),
  327. id="str_lt_str",
  328. ),
  329. rx.text(
  330. (VarOperationState.str_var1 >= VarOperationState.str_var2).to_string(),
  331. id="str_gte_str",
  332. ),
  333. rx.text(
  334. (VarOperationState.str_var1 <= VarOperationState.str_var2).to_string(),
  335. id="str_lte_str",
  336. ),
  337. rx.text(
  338. (
  339. VarOperationState.float_var1 == VarOperationState.float_var2
  340. ).to_string(),
  341. id="str_eq_str",
  342. ),
  343. rx.text(
  344. (
  345. VarOperationState.float_var1 != VarOperationState.float_var2
  346. ).to_string(),
  347. id="str_neq_str",
  348. ),
  349. rx.text(
  350. VarOperationState.str_var1.contains("fir").to_string(),
  351. id="str_contains",
  352. ),
  353. rx.text(
  354. VarOperationState.str_var1 | VarOperationState.str_var1, id="str_or_str"
  355. ),
  356. rx.text(
  357. VarOperationState.str_var1 & VarOperationState.str_var2,
  358. id="str_and_str",
  359. ),
  360. # STR, INT
  361. rx.text(
  362. VarOperationState.str_var1 * VarOperationState.int_var2,
  363. id="str_mult_int",
  364. ),
  365. rx.text(
  366. VarOperationState.str_var1 & VarOperationState.int_var2,
  367. id="str_and_int",
  368. ),
  369. rx.text(
  370. VarOperationState.str_var1 | VarOperationState.int_var2, id="str_or_int"
  371. ),
  372. rx.text(
  373. (VarOperationState.str_var1 == VarOperationState.int_var1).to_string(),
  374. id="str_eq_int",
  375. ),
  376. rx.text(
  377. (VarOperationState.str_var1 != VarOperationState.int_var1).to_string(),
  378. id="str_neq_int",
  379. ),
  380. # STR, LIST
  381. rx.text(
  382. VarOperationState.str_var1 | VarOperationState.list1, id="str_or_list"
  383. ),
  384. rx.text(
  385. (VarOperationState.str_var1 & VarOperationState.list1).to_string(),
  386. id="str_and_list",
  387. ),
  388. rx.text(
  389. (VarOperationState.str_var1 == VarOperationState.list1).to_string(),
  390. id="str_eq_list",
  391. ),
  392. rx.text(
  393. (VarOperationState.str_var1 != VarOperationState.list1).to_string(),
  394. id="str_neq_list",
  395. ),
  396. # STR, DICT
  397. rx.text(
  398. VarOperationState.str_var1 | VarOperationState.dict1, id="str_or_dict"
  399. ),
  400. rx.text(
  401. (VarOperationState.str_var1 & VarOperationState.dict1).to_string(),
  402. id="str_and_dict",
  403. ),
  404. rx.text(
  405. (VarOperationState.str_var1 == VarOperationState.dict1).to_string(),
  406. id="str_eq_dict",
  407. ),
  408. rx.text(
  409. (VarOperationState.str_var1 != VarOperationState.dict1).to_string(),
  410. id="str_neq_dict",
  411. ),
  412. # LIST, LIST
  413. rx.text(
  414. (VarOperationState.list1 + VarOperationState.list2).to_string(),
  415. id="list_add_list",
  416. ),
  417. rx.text(
  418. (VarOperationState.list1 & VarOperationState.list2).to_string(),
  419. id="list_and_list",
  420. ),
  421. rx.text(
  422. (VarOperationState.list1 | VarOperationState.list2).to_string(),
  423. id="list_or_list",
  424. ),
  425. rx.text(
  426. (VarOperationState.list1 > VarOperationState.list2).to_string(),
  427. id="list_gt_list",
  428. ),
  429. rx.text(
  430. (VarOperationState.list1 < VarOperationState.list2).to_string(),
  431. id="list_lt_list",
  432. ),
  433. rx.text(
  434. (VarOperationState.list1 >= VarOperationState.list2).to_string(),
  435. id="list_gte_list",
  436. ),
  437. rx.text(
  438. (VarOperationState.list1 <= VarOperationState.list2).to_string(),
  439. id="list_lte_list",
  440. ),
  441. rx.text(
  442. (VarOperationState.list1 == VarOperationState.list2).to_string(),
  443. id="list_eq_list",
  444. ),
  445. rx.text(
  446. (VarOperationState.list1 != VarOperationState.list2).to_string(),
  447. id="list_neq_list",
  448. ),
  449. rx.text(
  450. VarOperationState.list1.contains(1).to_string(), id="list_contains"
  451. ),
  452. rx.text(VarOperationState.list1.reverse().to_string(), id="list_reverse"),
  453. # LIST, INT
  454. rx.text(
  455. (VarOperationState.list1 * VarOperationState.int_var2).to_string(),
  456. id="list_mult_int",
  457. ),
  458. rx.text(
  459. (VarOperationState.list1 | VarOperationState.int_var1).to_string(),
  460. id="list_or_int",
  461. ),
  462. rx.text(
  463. (VarOperationState.list1 & VarOperationState.int_var1).to_string(),
  464. id="list_and_int",
  465. ),
  466. rx.text(
  467. (VarOperationState.list1 == VarOperationState.int_var1).to_string(),
  468. id="list_eq_int",
  469. ),
  470. rx.text(
  471. (VarOperationState.list1 != VarOperationState.int_var1).to_string(),
  472. id="list_neq_int",
  473. ),
  474. # LIST, DICT
  475. rx.text(
  476. (VarOperationState.list1 | VarOperationState.dict1).to_string(),
  477. id="list_or_dict",
  478. ),
  479. rx.text(
  480. (VarOperationState.list1 & VarOperationState.dict1).to_string(),
  481. id="list_and_dict",
  482. ),
  483. rx.text(
  484. (VarOperationState.list1 == VarOperationState.dict1).to_string(),
  485. id="list_eq_dict",
  486. ),
  487. rx.text(
  488. (VarOperationState.list1 != VarOperationState.dict1).to_string(),
  489. id="list_neq_dict",
  490. ),
  491. # DICT, DICT
  492. rx.text(
  493. (VarOperationState.dict1 | VarOperationState.dict2).to_string(),
  494. id="dict_or_dict",
  495. ),
  496. rx.text(
  497. (VarOperationState.dict1 & VarOperationState.dict2).to_string(),
  498. id="dict_and_dict",
  499. ),
  500. rx.text(
  501. (VarOperationState.dict1 == VarOperationState.dict2).to_string(),
  502. id="dict_eq_dict",
  503. ),
  504. rx.text(
  505. (VarOperationState.dict1 != VarOperationState.dict2).to_string(),
  506. id="dict_neq_dict",
  507. ),
  508. rx.text(
  509. VarOperationState.dict1.contains(1).to_string(), id="dict_contains"
  510. ),
  511. rx.text(VarOperationState.str_var3.lower(), id="str_lower"),
  512. rx.text(VarOperationState.str_var3.upper(), id="str_upper"),
  513. rx.text(VarOperationState.str_var4.split(" ").to_string(), id="str_split"),
  514. rx.text(VarOperationState.list3.join(""), id="list_join"),
  515. rx.text(VarOperationState.list3.join(","), id="list_join_comma"),
  516. )
  517. app.compile()
  518. @pytest.fixture(scope="session")
  519. def var_operations(tmp_path_factory) -> Generator[AppHarness, None, None]:
  520. """Start VarOperations app at tmp_path via AppHarness.
  521. Args:
  522. tmp_path_factory: pytest tmp_path_factory fixture
  523. Yields:
  524. running AppHarness instance
  525. """
  526. with AppHarness.create(
  527. root=tmp_path_factory.mktemp("var_operations"),
  528. app_source=VarOperations, # type: ignore
  529. ) as harness:
  530. assert harness.app_instance is not None, "app is not running"
  531. yield harness
  532. @pytest.fixture
  533. def driver(var_operations: AppHarness):
  534. """Get an instance of the browser open to the var operations app.
  535. Args:
  536. var_operations: harness for VarOperations app
  537. Yields:
  538. WebDriver instance.
  539. """
  540. driver = var_operations.frontend()
  541. try:
  542. token_input = driver.find_element(By.ID, "token")
  543. assert token_input
  544. # wait for the backend connection to send the token
  545. token = var_operations.poll_for_value(token_input)
  546. assert token is not None
  547. yield driver
  548. finally:
  549. driver.quit()
  550. def test_var_operations(driver, var_operations: AppHarness):
  551. """Test that the var operations produce the right results.
  552. Args:
  553. driver: selenium WebDriver open to the app
  554. var_operations: AppHarness for the var operations app
  555. """
  556. tests = [
  557. # int, int
  558. ("int_add_int", "15"),
  559. ("int_mult_int", "50"),
  560. ("int_sub_int", "5"),
  561. ("int_exp_int", "100000"),
  562. ("int_div_int", "2"),
  563. ("int_floor_int", "1"),
  564. ("int_mod_int", "0"),
  565. ("int_gt_int", "true"),
  566. ("int_lt_int", "false"),
  567. ("int_gte_int", "true"),
  568. ("int_lte_int", "false"),
  569. ("int_and_int", "5"),
  570. ("int_or_int", "10"),
  571. ("int_eq_int", "false"),
  572. ("int_neq_int", "true"),
  573. # int, float
  574. ("float_add_int", "15.5"),
  575. ("float_mult_int", "52.5"),
  576. ("float_sub_int", "5.5"),
  577. ("float_exp_int", "127628.15625"),
  578. ("float_div_int", "2.1"),
  579. ("float_floor_int", "1"),
  580. ("float_mod_int", "0.5"),
  581. ("float_gt_int", "true"),
  582. ("float_lt_int", "false"),
  583. ("float_gte_int", "true"),
  584. ("float_lte_int", "false"),
  585. ("float_eq_int", "false"),
  586. ("float_neq_int", "true"),
  587. ("float_and_int", "5"),
  588. ("float_or_int", "10.5"),
  589. # int, dict
  590. ("int_or_dict", "10"),
  591. ("int_and_dict", '{"1":2}'),
  592. ("int_eq_dict", "false"),
  593. ("int_neq_dict", "true"),
  594. # float, float
  595. ("float_add_float", "16"),
  596. ("float_mult_float", "57.75"),
  597. ("float_sub_float", "5"),
  598. ("float_exp_float", "413562.49323606625"),
  599. ("float_div_float", "1.9090909090909092"),
  600. ("float_floor_float", "1"),
  601. ("float_mod_float", "5"),
  602. ("float_gt_float", "true"),
  603. ("float_lt_float", "false"),
  604. ("float_gte_float", "true"),
  605. ("float_lte_float", "false"),
  606. ("float_eq_float", "false"),
  607. ("float_neq_float", "true"),
  608. ("float_and_float", "5.5"),
  609. ("float_or_float", "10.5"),
  610. # float, str
  611. ("float_or_str", "10.5"),
  612. ("float_and_str", "first"),
  613. ("float_eq_str", "false"),
  614. ("float_neq_str", "true"),
  615. # float, list
  616. ("float_or_list", "10.5"),
  617. ("float_and_list", "[1,2]"),
  618. ("float_eq_list", "false"),
  619. ("float_neq_list", "true"),
  620. # float, dict
  621. ("float_or_dict", "10.5"),
  622. ("float_and_dict", '{"1":2}'),
  623. ("float_eq_dict", "false"),
  624. ("float_neq_dict", "true"),
  625. # str, str
  626. ("str_add_str", "firstsecond"),
  627. ("str_gt_str", "false"),
  628. ("str_lt_str", "true"),
  629. ("str_gte_str", "false"),
  630. ("str_lte_str", "true"),
  631. ("str_eq_str", "false"),
  632. ("str_neq_str", "true"),
  633. ("str_and_str", "second"),
  634. ("str_or_str", "first"),
  635. ("str_contains", "true"),
  636. ("str_lower", "third"),
  637. ("str_upper", "THIRD"),
  638. ("str_split", '["a","long","string"]'),
  639. # str, int
  640. ("str_mult_int", "firstfirstfirstfirstfirst"),
  641. ("str_and_int", "5"),
  642. ("str_or_int", "first"),
  643. ("str_eq_int", "false"),
  644. ("str_neq_int", "true"),
  645. # str, list
  646. ("str_and_list", "[1,2]"),
  647. ("str_or_list", "first"),
  648. ("str_eq_list", "false"),
  649. ("str_neq_list", "true"),
  650. # str, dict
  651. ("str_or_dict", "first"),
  652. ("str_and_dict", '{"1":2}'),
  653. ("str_eq_dict", "false"),
  654. ("str_neq_dict", "true"),
  655. # list, list
  656. ("list_add_list", "[1,2,3,4]"),
  657. ("list_gt_list", "false"),
  658. ("list_lt_list", "true"),
  659. ("list_gte_list", "false"),
  660. ("list_lte_list", "true"),
  661. ("list_eq_list", "false"),
  662. ("list_neq_list", "true"),
  663. ("list_and_list", "[3,4]"),
  664. ("list_or_list", "[1,2]"),
  665. ("list_contains", "true"),
  666. ("list_reverse", "[2,1]"),
  667. ("list_join", "firstsecondthird"),
  668. ("list_join_comma", "first,second,third"),
  669. # list, int
  670. ("list_mult_int", "[1,2,1,2,1,2,1,2,1,2]"),
  671. ("list_or_int", "[1,2]"),
  672. ("list_and_int", "10"),
  673. ("list_eq_int", "false"),
  674. ("list_neq_int", "true"),
  675. # list, dict
  676. ("list_and_dict", '{"1":2}'),
  677. ("list_or_dict", "[1,2]"),
  678. ("list_eq_dict", "false"),
  679. ("list_neq_dict", "true"),
  680. # dict, dict
  681. ("dict_or_dict", '{"1":2}'),
  682. ("dict_and_dict", '{"3":4}'),
  683. ("dict_eq_dict", "false"),
  684. ("dict_neq_dict", "true"),
  685. ("dict_contains", "true"),
  686. ]
  687. for tag, expected in tests:
  688. assert driver.find_element(By.ID, tag).text == expected