Bug 35598: Fix selenium/authentication_2fa.t random failure

Jenkins is failing with
koha_1       | STRACE:	/usr/share/perl5/Try/Tiny.pm:123 in Selenium::Remote::Driver::catch {...}
koha_1       | 	/usr/share/perl5/Selenium/Remote/Driver.pm:361 in Try::Tiny::try
koha_1       | 	(eval 582):1 in Selenium::Remote::Driver::__ANON__
koha_1       | 	(eval 584):2 in Selenium::Remote::Driver::__ANON__
koha_1       | 	(eval 556):17 in Selenium::Remote::Driver::_execute_command
koha_1       | 	/usr/share/perl5/Selenium/Remote/WebElement.pm:125 in Selenium::Remote::WebElement::_execute_command
koha_1       | 	t/db_dependent/selenium/authentication_2fa.t:276 in Selenium::Remote::WebElement::send_keys
koha_1       | 	/usr/share/perl/5.32/Test/Builder.pm:334 in main::__ANON__
koha_1       | 	/usr/share/perl/5.32/Test/Builder.pm:334 in (eval)
koha_1       | 	/usr/share/perl/5.32/Test/More.pm:809 in Test::Builder::subtest
koha_1       | 	t/db_dependent/selenium/authentication_2fa.t:294 in Test::More::subtest
koha_1       |
selenium_1   | 1702911648831	Marionette	INFO	Stopped listening on port 41385
selenium_1   | JavaScript error: resource:///modules/Interactions.jsm, line 230: NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIUserIdleService.removeIdleObserver]
selenium_1   | 15:00:49.452 INFO [ActiveSessions$1.onStop] - Removing session c3461b22-7a80-4b56-b177-653a53cc2651 (org.openqa.selenium.firefox.GeckoDriverService)
koha_1       |     # Looks like you planned 7 tests but ran 3.
koha_1       |
koha_1       | #   Failed test 'Enforce 2FA setup on first login'
koha_1       | #   at t/db_dependent/selenium/authentication_2fa.t line 294.
koha_1       | Error while executing command: element not interactable: Element <input id="pin_code" name="pin_code" type="text"> is not reachable by keyboard at /usr/share/perl5/Selenium/Remote/Driver.pm line 411.

The error is: "Element <input id="pin_code" name="pin_code" type="text"> is not reachable by keyboard"

A guess is that the input is either 1. outside of the viewport, or 2. not
displayed yet.

1. We are hidding #registration-form then show it when we retrieved the
   info (after POST /api/v1/auth/two-factor/registration)
2. Couldn't there be a race condition?
In auth.tt
284                     success: function (data) {
292                         $("#registration-form").show();
And in the selenium test:
$s->wait_for_ajax; # There is an ajax request to populate the qr_code and the secret
Not sure this wait_for_ajax is waiting for the end of success, I don't
think so.

This patch is supposed to fix both theories.

Test plan:
0. Do not apply the patch
1. Edit auth.tt and sleep 1 second before showing the form:
290                         const sleep = ms => new Promise(r => setTimeout(r, ms));
291                         await sleep(1000);
292                         $("#registration-form").show();

You will also need to replace the following line (284):
  success: function (data) {
with
  success: async function (data) {

2. prove t/db_dependent/selenium/authentication_2fa.t
=> "is not reachable by keyboard" error!

3. Apply the patch, keep the sleep

4. prove t/db_dependent/selenium/authentication_2fa.t
=> Tests are passing

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Edit (tcohen): Tidied a bit to clear complaints
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
(cherry picked from commit 3270d32191)
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
(cherry picked from commit 5aa213e210)
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Jonathan Druart 2023-12-19 10:28:30 +01:00 committed by Lucas Gass
parent ba485664db
commit 34cefad0ae

View file

@ -265,6 +265,8 @@ SKIP: {
);
$s->wait_for_ajax; # There is an ajax request to populate the qr_code and the secret
$driver->set_window_size( 3840, 1080 );
$s->wait_for_element_visible('//*[@id="registration-form"]');
isnt( $driver->find_element('//*[@id="qr_code"]')->get_attribute("src"), "" );
my $secret32 = $driver->find_element('//*[@id="secret32"]')->get_value;