summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2024-10-22 13:38:50 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-10-24 11:24:03 +0100
commit1f2b8a27ead94d48148111c00f11056e328c03eb (patch)
tree7945eedb876593d2bad736f00eaea7501e5d4972
parent7fef43d98a20cc8267adad55c46fb96f6bb026d7 (diff)
downloadpoky-1f2b8a27ead94d48148111c00f11056e328c03eb.tar.gz
bitbake: toaster/tests/functional/project_page: Use wait_until_element_clickable before click calls
Switch the clickable() calls to use the new element_clickable() function which accepts a finder labmda function. This means if the element doesn't yet exist, the code can rebuild the query and try again once a small amount of time has elapsed. There were a ton of timing related races around these element interactions and this seemed to be the most robust way to address the issues. The change also makes some of the elements slightly more specific so the code can work effectively. (Bitbake rev: 38643aadbb5a960004b886cf7709beaf2fc96652) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/toaster/tests/functional/test_project_page.py93
1 files changed, 40 insertions, 53 deletions
diff --git a/bitbake/lib/toaster/tests/functional/test_project_page.py b/bitbake/lib/toaster/tests/functional/test_project_page.py
index f34ccf5e8e..c6dad0eb5d 100644
--- a/bitbake/lib/toaster/tests/functional/test_project_page.py
+++ b/bitbake/lib/toaster/tests/functional/test_project_page.py
@@ -92,7 +92,8 @@ class TestProjectPageBase(SeleniumFunctionalTestCase):
92 list_check_box_id: list 92 list_check_box_id: list
93 ): 93 ):
94 # Check edit column 94 # Check edit column
95 edit_column = self.find(f'#{edit_btn_id}') 95 finder = lambda driver: self.find(f'#{edit_btn_id}')
96 edit_column = self.wait_until_element_clickable(finder)
96 self.assertTrue(edit_column.is_displayed()) 97 self.assertTrue(edit_column.is_displayed())
97 edit_column.click() 98 edit_column.click()
98 # Check dropdown is visible 99 # Check dropdown is visible
@@ -280,7 +281,8 @@ class TestProjectPage(TestProjectPageBase):
280 281
281 # click on "Edit" icon button 282 # click on "Edit" icon button
282 self.wait_until_visible('#project-name-container') 283 self.wait_until_visible('#project-name-container')
283 edit_button = self.find('#project-change-form-toggle') 284 finder = lambda driver: self.find('#project-change-form-toggle')
285 edit_button = self.wait_until_element_clickable(finder)
284 edit_button.click() 286 edit_button.click()
285 project_name_input = self.find('#project-name-change-input') 287 project_name_input = self.find('#project-name-change-input')
286 self.assertTrue(project_name_input.is_displayed()) 288 self.assertTrue(project_name_input.is_displayed())
@@ -391,12 +393,8 @@ class TestProjectPage(TestProjectPageBase):
391 table_selector='softwarerecipestable' 393 table_selector='softwarerecipestable'
392 ) 394 )
393 # check "build recipe" button works 395 # check "build recipe" button works
394 rows = self.find_all('#softwarerecipestable tbody tr') 396 finder = lambda driver: self.find_all('#softwarerecipestable tbody tr')[0].find_element(By.XPATH, '//td[@class="add-del-layers"]/a')
395 image_to_build = rows[0] 397 build_btn = self.wait_until_element_clickable(finder)
396 build_btn = image_to_build.find_element(
397 By.XPATH,
398 '//td[@class="add-del-layers"]//a[1]'
399 )
400 build_btn.click() 398 build_btn.click()
401 build_state = wait_until_build(self, 'queued cloning starting parsing failed') 399 build_state = wait_until_build(self, 'queued cloning starting parsing failed')
402 lastest_builds = self.driver.find_elements( 400 lastest_builds = self.driver.find_elements(
@@ -404,11 +402,10 @@ class TestProjectPage(TestProjectPageBase):
404 '//div[@id="latest-builds"]/div' 402 '//div[@id="latest-builds"]/div'
405 ) 403 )
406 self.assertTrue(len(lastest_builds) > 0) 404 self.assertTrue(len(lastest_builds) > 0)
407 last_build = lastest_builds[0] 405 # Find the latest builds, the last build and then the cancel button
408 cancel_button = last_build.find_element( 406
409 By.XPATH, 407 finder = lambda driver: driver.find_elements(By.XPATH, '//div[@id="latest-builds"]/div')[0].find_element(By.XPATH, '//span[@class="cancel-build-btn pull-right alert-link"]')
410 '//span[@class="cancel-build-btn pull-right alert-link"]', 408 cancel_button = self.wait_until_element_clickable(finder)
411 )
412 cancel_button.click() 409 cancel_button.click()
413 if 'starting' not in build_state: # change build state when cancelled in starting state 410 if 'starting' not in build_state: # change build state when cancelled in starting state
414 wait_until_build_cancelled(self) 411 wait_until_build_cancelled(self)
@@ -455,14 +452,10 @@ class TestProjectPage(TestProjectPageBase):
455 table_selector='machinestable' 452 table_selector='machinestable'
456 ) 453 )
457 # check "Select machine" button works 454 # check "Select machine" button works
458 rows = self.find_all('#machinestable tbody tr') 455 finder = lambda driver: self.find_all('#machinestable tbody tr')[0].find_element(By.XPATH, '//td[@class="add-del-layers"]')
459 machine_to_select = rows[0] 456 select_btn = self.wait_until_element_clickable(finder)
460 select_btn = machine_to_select.find_element( 457 select_btn.click()
461 By.XPATH, 458 self.wait_until_visible('#project-machine-name')
462 '//td[@class="add-del-layers"]//a[1]'
463 )
464 select_btn.send_keys(Keys.RETURN)
465 self.wait_until_visible('#config-nav')
466 project_machine_name = self.find('#project-machine-name') 459 project_machine_name = self.find('#project-machine-name')
467 self.assertIn( 460 self.assertIn(
468 'qemux86-64', project_machine_name.text 461 'qemux86-64', project_machine_name.text
@@ -478,9 +471,9 @@ class TestProjectPage(TestProjectPageBase):
478 ) 471 )
479 472
480 self.wait_until_visible('#machinestable tbody tr') 473 self.wait_until_visible('#machinestable tbody tr')
481 rows = self.find_all('#machinestable tbody tr') 474 # Locate a machine to add button
482 machine_to_add = rows[0] 475 finder = lambda driver: self.find_all('#machinestable tbody tr')[0].find_element(By.XPATH, '//td[@class="add-del-layers"]')
483 add_btn = machine_to_add.find_element(By.XPATH, '//td[@class="add-del-layers"]') 476 add_btn = self.wait_until_element_clickable(finder)
484 add_btn.click() 477 add_btn.click()
485 self.wait_until_visible('#change-notification') 478 self.wait_until_visible('#change-notification')
486 change_notification = self.find('#change-notification') 479 change_notification = self.find('#change-notification')
@@ -488,7 +481,8 @@ class TestProjectPage(TestProjectPageBase):
488 f'You have added 1 layer to your project', str(change_notification.text) 481 f'You have added 1 layer to your project', str(change_notification.text)
489 ) 482 )
490 483
491 hide_button = self.find('#hide-alert') 484 finder = lambda driver: self.find('#hide-alert')
485 hide_button = self.wait_until_element_clickable(finder)
492 hide_button.click() 486 hide_button.click()
493 self.wait_until_not_visible('#change-notification') 487 self.wait_until_not_visible('#change-notification')
494 488
@@ -533,21 +527,15 @@ class TestProjectPage(TestProjectPageBase):
533 ) 527 )
534 # check "Add layer" button works 528 # check "Add layer" button works
535 self.wait_until_visible('#layerstable tbody tr') 529 self.wait_until_visible('#layerstable tbody tr')
536 rows = self.find_all('#layerstable tbody tr') 530 finder = lambda driver: self.find_all('#layerstable tbody tr')[0].find_element(By.XPATH, '//td[@class="add-del-layers"]/a[@data-directive="add"]')
537 layer_to_add = rows[0] 531 add_btn = self.wait_until_element_clickable(finder)
538 add_btn = layer_to_add.find_element(
539 By.XPATH,
540 '//td[@class="add-del-layers"]'
541 )
542 add_btn.click() 532 add_btn.click()
543 # check modal is displayed 533 # check modal is displayed
544 self.wait_until_visible('#dependencies-modal') 534 self.wait_until_visible('#dependencies-modal')
545 list_dependencies = self.find_all('#dependencies-list li') 535 list_dependencies = self.find_all('#dependencies-list li')
546 # click on add-layers button 536 # click on add-layers button
547 add_layers_btn = self.driver.find_element( 537 finder = lambda driver: self.driver.find_element(By.XPATH, '//form[@id="dependencies-modal-form"]//button[@class="btn btn-primary"]')
548 By.XPATH, 538 add_layers_btn = self.wait_until_element_clickable(finder)
549 '//form[@id="dependencies-modal-form"]//button[@class="btn btn-primary"]'
550 )
551 add_layers_btn.click() 539 add_layers_btn.click()
552 self.wait_until_visible('#change-notification') 540 self.wait_until_visible('#change-notification')
553 change_notification = self.find('#change-notification') 541 change_notification = self.find('#change-notification')
@@ -555,18 +543,15 @@ class TestProjectPage(TestProjectPageBase):
555 f'You have added {len(list_dependencies)+1} layers to your project: {input_text} and its dependencies', str(change_notification.text) 543 f'You have added {len(list_dependencies)+1} layers to your project: {input_text} and its dependencies', str(change_notification.text)
556 ) 544 )
557 545
558 hide_button = self.find('#hide-alert') 546 finder = lambda driver: self.find('#hide-alert')
547 hide_button = self.wait_until_element_clickable(finder)
559 hide_button.click() 548 hide_button.click()
560 self.wait_until_not_visible('#change-notification') 549 self.wait_until_not_visible('#change-notification')
561 550
562 # check "Remove layer" button works 551 # check "Remove layer" button works
563 self.wait_until_visible('#layerstable tbody tr') 552 self.wait_until_visible('#layerstable tbody tr')
564 rows = self.find_all('#layerstable tbody tr') 553 finder = lambda driver: self.find_all('#layerstable tbody tr')[0].find_element(By.XPATH, '//td[@class="add-del-layers"]/a[@data-directive="remove"]')
565 layer_to_remove = rows[0] 554 remove_btn = self.wait_until_element_clickable(finder)
566 remove_btn = layer_to_remove.find_element(
567 By.XPATH,
568 '//td[@class="add-del-layers"]'
569 )
570 remove_btn.click() 555 remove_btn.click()
571 self.wait_until_visible('#change-notification') 556 self.wait_until_visible('#change-notification')
572 change_notification = self.find('#change-notification') 557 change_notification = self.find('#change-notification')
@@ -574,7 +559,8 @@ class TestProjectPage(TestProjectPageBase):
574 f'You have removed 1 layer from your project: {input_text}', str(change_notification.text) 559 f'You have removed 1 layer from your project: {input_text}', str(change_notification.text)
575 ) 560 )
576 561
577 hide_button = self.find('#hide-alert') 562 finder = lambda driver: self.find('#hide-alert')
563 hide_button = self.wait_until_element_clickable(finder)
578 hide_button.click() 564 hide_button.click()
579 self.wait_until_not_visible('#change-notification') 565 self.wait_until_not_visible('#change-notification')
580 566
@@ -618,12 +604,9 @@ class TestProjectPage(TestProjectPageBase):
618 table_selector='distrostable' 604 table_selector='distrostable'
619 ) 605 )
620 # check "Add distro" button works 606 # check "Add distro" button works
621 rows = self.find_all('#distrostable tbody tr') 607 self.wait_until_visible(".add-del-layers")
622 distro_to_add = rows[0] 608 finder = lambda driver: self.find_all('#distrostable tbody tr')[0].find_element(By.XPATH, '//td[@class="add-del-layers"]')
623 add_btn = distro_to_add.find_element( 609 add_btn = self.wait_until_element_clickable(finder)
624 By.XPATH,
625 '//td[@class="add-del-layers"]//a[1]'
626 )
627 add_btn.click() 610 add_btn.click()
628 self.wait_until_visible('#change-notification') 611 self.wait_until_visible('#change-notification')
629 change_notification = self.find('#change-notification') 612 change_notification = self.find('#change-notification')
@@ -668,25 +651,29 @@ class TestProjectPage(TestProjectPageBase):
668 self.assertTrue(self.find('.page-header h1').is_displayed()) 651 self.assertTrue(self.find('.page-header h1').is_displayed())
669 652
670 # check remove layer button works 653 # check remove layer button works
671 remove_layer_btn = self.find('#add-remove-layer-btn') 654 finder = lambda driver: self.find('#add-remove-layer-btn')
655 remove_layer_btn = self.wait_until_element_clickable(finder)
672 remove_layer_btn.click() 656 remove_layer_btn.click()
673 self.wait_until_visible('#change-notification') 657 self.wait_until_visible('#change-notification')
674 change_notification = self.find('#change-notification') 658 change_notification = self.find('#change-notification')
675 self.assertIn( 659 self.assertIn(
676 f'You have removed 1 layer from your project', str(change_notification.text) 660 f'You have removed 1 layer from your project', str(change_notification.text)
677 ) 661 )
678 hide_button = self.find('#hide-alert') 662 finder = lambda driver: self.find('#hide-alert')
663 hide_button = self.wait_until_element_clickable(finder)
679 hide_button.click() 664 hide_button.click()
680 # check add layer button works 665 # check add layer button works
681 self.wait_until_not_visible('#change-notification') 666 self.wait_until_not_visible('#change-notification')
682 add_layer_btn = self.find('#add-remove-layer-btn') 667 finder = lambda driver: self.find('#add-remove-layer-btn')
668 add_layer_btn = self.wait_until_element_clickable(finder)
683 add_layer_btn.click() 669 add_layer_btn.click()
684 self.wait_until_visible('#change-notification') 670 self.wait_until_visible('#change-notification')
685 change_notification = self.find('#change-notification') 671 change_notification = self.find('#change-notification')
686 self.assertIn( 672 self.assertIn(
687 f'You have added 1 layer to your project', str(change_notification.text) 673 f'You have added 1 layer to your project', str(change_notification.text)
688 ) 674 )
689 hide_button = self.find('#hide-alert') 675 finder = lambda driver: self.find('#hide-alert')
676 hide_button = self.wait_until_element_clickable(finder)
690 hide_button.click() 677 hide_button.click()
691 self.wait_until_not_visible('#change-notification') 678 self.wait_until_not_visible('#change-notification')
692 # check tabs(layers, recipes, machines) are displayed 679 # check tabs(layers, recipes, machines) are displayed