From 04b625a597f23229ac8fe9671c108b3cc0cdb591 Mon Sep 17 00:00:00 2001 From: Josh Hernandez Date: Fri, 26 Jul 2024 01:22:43 -0400 Subject: [PATCH 1/4] Refactor institutions login test --- pages/login.py | 8 ++++- tests/test_login.py | 84 ++++++++++++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/pages/login.py b/pages/login.py index 80b43b48..ee57affd 100644 --- a/pages/login.py +++ b/pages/login.py @@ -102,10 +102,16 @@ class GenericInstitutionEmailLoginPage(BasePage): class GenericInstitutionUsernameLoginPage(BasePage): # This is for institution login pages that first ask for a Username or User ID to # initiate the login process before asking for a password. The page has a form - # element and a usenrname or user id text input box. + # element and a username or user id text input box. identity = Locator(By.CSS_SELECTOR, 'form[method="post"]') +class GenericInstitutionIDLoginPage(BasePage): + # This is for institution login pages that first ask for a User ID to + # initiate the login process before asking for a password. + identity = Locator(By.CSS_SELECTOR, 'input[autocomplete="username"]') + + class ForgotPasswordPage(BasePage): url = settings.OSF_HOME + '/forgotpassword/' diff --git a/tests/test_login.py b/tests/test_login.py index f3f02e42..3e0ec73b 100644 --- a/tests/test_login.py +++ b/tests/test_login.py @@ -15,6 +15,7 @@ ForgotPasswordPage, GenericCASPage, GenericInstitutionEmailLoginPage, + GenericInstitutionIDLoginPage, GenericInstitutionLoginPage, GenericInstitutionUsernameLoginPage, InstitutionalLoginPage, @@ -330,6 +331,17 @@ def test_account_disabled_page(self, driver): assert exception_page.status_message.text == 'Account disabled' +def try_login_page(driver, page_class): + """ + Helper function to try and verify a login page. + Returns True if successful, otherwise False. + """ + try: + return page_class(driver, verify=True) + except (PageException, NoSuchElementException): + return False + + @markers.smoke_test @markers.core_functionality class TestInstitutionLoginPage: @@ -415,40 +427,50 @@ def test_individual_institution_login_pages( not have working testing environments. """ failed_list = [] + for institution in institution_list: - if institution != '-- select an institution --': - institution_select = Select(institution_login_page.institution_dropdown) - institution_select.select_by_visible_text(institution) - institution_login_page.sign_in_button.click() + # This value represents a placeholder or default option in the dropdown list, + # which isn't a valid institution for testing. Avoid wrapping the rest of the loop's logic + # in an additional if statement by using an early continue + if institution == '-- select an institution --': + continue + + # Select institution and click sign in + Select(institution_login_page.institution_dropdown).select_by_visible_text( + institution + ) + institution_login_page.sign_in_button.click() + + try: + # Verify that we get to a valid login page by checking for a + # password input field + assert GenericInstitutionLoginPage(driver, verify=True) + except PageException: try: - # Verify that we get to a valid login page by checking for a - # password input field - assert GenericInstitutionLoginPage(driver, verify=True) - except PageException: - try: - # For a small number of institutions the initial login page - # first asks for just an email without the passord field. - assert GenericInstitutionEmailLoginPage(driver, verify=True) - except PageException: - try: + # Try different login page verifications + if not any( + [ + # For a small number of institutions the initial login page + # first asks for just an email without the password field. + try_login_page(driver, GenericInstitutionEmailLoginPage), # A few institutions use a login page with a generic username - # or user id text input field. The page definition checks for - # a form element with methdo="post". Then check that the page - # also has an input box. - assert GenericInstitutionUsernameLoginPage( - driver, verify=True - ) - driver.find_element(By.CSS_SELECTOR, 'input[type="text"]') - except (PageException, NoSuchElementException): - # if there is a failure add the name of the institution to the - # failed list - failed_list.append(institution) - # Need to go back to the original OSF Institution Login page - institution_login_page.goto() - # If there are any failed institutions then fail the test and print the list - assert len(failed_list) == 0, 'The following Institutions Failed: ' + str( - failed_list - ) + # or user id text input field. + try_login_page(driver, GenericInstitutionUsernameLoginPage), + # Chicago University has autocomplete="username" + try_login_page(driver, GenericInstitutionIDLoginPage), + ] + ): + failed_list.append(institution) + except Exception as e: + failed_list.append(institution) + + # Return to the original OSF Institution Login page + institution_login_page.goto() + + # Fail the test if there are any failed institutions and print the list + assert ( + len(failed_list) == 0 + ), f'The following Institutions Failed: {failed_list}' @markers.dont_run_on_prod From d44858942561fe5ddf677b9384b34d5d868dba11 Mon Sep 17 00:00:00 2001 From: Josh Hernandez Date: Mon, 29 Jul 2024 21:40:02 -0400 Subject: [PATCH 2/4] Refactor institutions login test --- tests/test_login.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/test_login.py b/tests/test_login.py index 3e0ec73b..369c709f 100644 --- a/tests/test_login.py +++ b/tests/test_login.py @@ -441,27 +441,29 @@ def test_individual_institution_login_pages( ) institution_login_page.sign_in_button.click() + success = False + page_classes = [ + GenericInstitutionEmailLoginPage, + GenericInstitutionUsernameLoginPage, + GenericInstitutionIDLoginPage, + ] + try: # Verify that we get to a valid login page by checking for a # password input field assert GenericInstitutionLoginPage(driver, verify=True) except PageException: - try: - # Try different login page verifications - if not any( - [ - # For a small number of institutions the initial login page - # first asks for just an email without the password field. - try_login_page(driver, GenericInstitutionEmailLoginPage), - # A few institutions use a login page with a generic username - # or user id text input field. - try_login_page(driver, GenericInstitutionUsernameLoginPage), - # Chicago University has autocomplete="username" - try_login_page(driver, GenericInstitutionIDLoginPage), - ] - ): - failed_list.append(institution) - except Exception as e: + # For a small number of institutions the initial login page + # first asks for just an email without the password field. + # A few institutions use a login page with a generic username + # or user id text input field. The page definition checks for + # a form element with method="post". + for page_class in page_classes: + retval = try_login_page(driver, page_class) + if retval: + success = True + break + if not success: failed_list.append(institution) # Return to the original OSF Institution Login page From 796a23eae409048b6f3e753186bc224d209306ab Mon Sep 17 00:00:00 2001 From: Josh Hernandez Date: Fri, 2 Aug 2024 11:37:09 -0400 Subject: [PATCH 3/4] Code review fix --- tests/test_login.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/tests/test_login.py b/tests/test_login.py index 369c709f..71a7d7b3 100644 --- a/tests/test_login.py +++ b/tests/test_login.py @@ -443,28 +443,27 @@ def test_individual_institution_login_pages( success = False page_classes = [ + GenericInstitutionLoginPage, GenericInstitutionEmailLoginPage, GenericInstitutionUsernameLoginPage, GenericInstitutionIDLoginPage, ] - try: - # Verify that we get to a valid login page by checking for a - # password input field - assert GenericInstitutionLoginPage(driver, verify=True) - except PageException: - # For a small number of institutions the initial login page - # first asks for just an email without the password field. - # A few institutions use a login page with a generic username - # or user id text input field. The page definition checks for - # a form element with method="post". - for page_class in page_classes: - retval = try_login_page(driver, page_class) - if retval: - success = True - break - if not success: - failed_list.append(institution) + # GILoginPage - Verify that we get to a valid login page by checking for a + # password input field + # GIEmailLoginPage - For a small number of institutions the initial login page + # first asks for just an email without the password field. + # GIUsernameLoginPage - A few institutions use a login page with a generic username + # or user id text input field. The page definition checks for + # a form element with method="post". + # GIDLoginPage - Check for institutions that use OKTA for sign in + for page_class in page_classes: + retval = try_login_page(driver, page_class) + if retval: + success = True + break + if not success: + failed_list.append(institution) # Return to the original OSF Institution Login page institution_login_page.goto() From 8fb41955281f8e8d5b53649fdd7252fe7bce9412 Mon Sep 17 00:00:00 2001 From: Josh Hernandez Date: Fri, 2 Aug 2024 11:54:30 -0400 Subject: [PATCH 4/4] Update docstrings --- tests/test_login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_login.py b/tests/test_login.py index 71a7d7b3..da8e5c79 100644 --- a/tests/test_login.py +++ b/tests/test_login.py @@ -456,7 +456,7 @@ def test_individual_institution_login_pages( # GIUsernameLoginPage - A few institutions use a login page with a generic username # or user id text input field. The page definition checks for # a form element with method="post". - # GIDLoginPage - Check for institutions that use OKTA for sign in + # GIIDLoginPage - Check for institutions that use Okta for sign in for page_class in page_classes: retval = try_login_page(driver, page_class) if retval: