Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable e2e tests on SauceLabs in IE11 for Gen3 and Gen2 #3669

Merged
merged 14 commits into from
Sep 4, 2024
18 changes: 16 additions & 2 deletions .bacon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,16 @@ test_suites:
- name: e2e-saucelabs
script_path: /root/okta/okta-signin-widget/scripts
sort_order: '14'
timeout: '20'
timeout: '30'
script_name: e2e-saucelabs
criteria: MERGE
criteria: OPTIONAL
queue_name: small
- name: e2e-saucelabs-v3
script_path: /root/okta/okta-signin-widget/scripts
sort_order: '15'
timeout: '30'
script_name: e2e-saucelabs-v3
criteria: OPTIONAL
queue_name: small
# Optional test suite until Android is enabled
- name: e2e-saucelabs-mobile
Expand All @@ -108,6 +115,13 @@ test_suites:
script_name: e2e-saucelabs-mobile
criteria: OPTIONAL
queue_name: small
- name: e2e-saucelabs-mobile-v3
script_path: /root/okta/okta-signin-widget/scripts
sort_order: '16'
timeout: '20'
script_name: e2e-saucelabs-mobile-v3
criteria: OPTIONAL
lesterchoi-okta marked this conversation as resolved.
Show resolved Hide resolved
queue_name: small
- name: tsd
script_path: /root/okta/okta-signin-widget/scripts
sort_order: '16'
Expand Down
50 changes: 50 additions & 0 deletions scripts/e2e-saucelabs-mobile-v3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash
export CI=true

source $OKTA_HOME/$REPO/scripts/setup.sh

setup_service java 1.8.222

export RUN_SAUCE_TESTS=mobile
export SAUCE_USERNAME=OktaSignInWidget
get_vault_secret_key devex/sauce-labs accessKey SAUCE_ACCESS_KEY
export TEST_SUITE_TYPE="junit"
export TEST_RESULT_FILE_DIR="${REPO}/build2"
echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE}
echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE}

# We use the below OIE enabled org and clients for OIE tests
export WIDGET_TEST_SERVER=https://oie-signin-widget.okta.com
export WIDGET_SPA_CLIENT_ID=0oa8lrg7ojTsbJgRQ696
export WIDGET_WEB_CLIENT_ID=0oa8ls36zUZj7oFJ2696
export WIDGET_BASIC_USER=testuser
get_vault_secret_key devex/okta-signin-widget widget_basic_password WIDGET_BASIC_PASSWORD

export ORG_OIE_ENABLED=true
get_vault_secret_key devex/auth-js-sdk-vars a18n_api_key A18N_API_KEY
get_vault_secret_key devex/okta-signin-widget test_org_okta_api_key OKTA_CLIENT_TOKEN

# Build
if ! yarn workspace v3 build:release; then
echo "build failed! Exiting..."
exit ${TEST_FAILURE}
fi

if ! setup_service node v14.18.2 &> /dev/null; then
echo "Failed to install node"
exit ${FAILED_SETUP}
fi

# Run tests
export DISABLE_CSP=1
export CDN_ONLY=1
export BUNDLE="next"
export TARGET="CROSS_BROWSER"
export USE_MIN=1

if ! yarn test:e2e; then
echo "e2e saucelabs test failed! Exiting..."
exit ${PUBLISH_TYPE_AND_RESULT_DIR_BUT_ALWAYS_FAIL}
fi

exit ${PUBLISH_TYPE_AND_RESULT_DIR}
15 changes: 9 additions & 6 deletions scripts/e2e-saucelabs-mobile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ export CI=true
source $OKTA_HOME/$REPO/scripts/setup.sh

setup_service java 1.8.222
setup_service google-chrome-stable 89.0.4389.72-1

export RUN_SAUCE_TESTS=true
export MOBILE_BROWSER_TESTS=true
export RUN_SAUCE_TESTS=mobile
export SAUCE_USERNAME=OktaSignInWidget
get_vault_secret_key devex/sauce-labs accessKey SAUCE_ACCESS_KEY
export TEST_SUITE_TYPE="junit"
export TEST_RESULT_FILE_DIR="${REPO}/build2"
echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE}
echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE}

# We use the below OIE enabled org and clients for OIE tests
export WIDGET_TEST_SERVER=https://oie-signin-widget.okta.com
Expand All @@ -30,13 +30,16 @@ if ! yarn build:release; then
exit ${TEST_FAILURE}
fi

if ! setup_service node v14.18.2 &> /dev/null; then
echo "Failed to install node"
exit ${FAILED_SETUP}
fi

export CDN_ONLY=1
export TARGET="CROSS_BROWSER"
if ! yarn test:e2e; then
echo "e2e sauce.baconlabs mobile test failed! Exiting..."
exit ${TEST_FAILURE}
exit ${PUBLISH_TYPE_AND_RESULT_DIR_BUT_ALWAYS_FAIL}
fi

echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE}
echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE}
exit ${PUBLISH_TYPE_AND_RESULT_DIR}
50 changes: 50 additions & 0 deletions scripts/e2e-saucelabs-v3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash
export CI=true

source $OKTA_HOME/$REPO/scripts/setup.sh

setup_service java 1.8.222

export RUN_SAUCE_TESTS=ie11
export SAUCE_USERNAME=OktaSignInWidget
get_vault_secret_key devex/sauce-labs accessKey SAUCE_ACCESS_KEY
export TEST_SUITE_TYPE="junit"
export TEST_RESULT_FILE_DIR="${REPO}/build2"
echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE}
echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE}

# We use the below OIE enabled org and clients for OIE tests
export WIDGET_TEST_SERVER=https://oie-signin-widget.okta.com
export WIDGET_SPA_CLIENT_ID=0oa8lrg7ojTsbJgRQ696
export WIDGET_WEB_CLIENT_ID=0oa8ls36zUZj7oFJ2696
export WIDGET_BASIC_USER=testuser
get_vault_secret_key devex/okta-signin-widget widget_basic_password WIDGET_BASIC_PASSWORD

export ORG_OIE_ENABLED=true
get_vault_secret_key devex/auth-js-sdk-vars a18n_api_key A18N_API_KEY
get_vault_secret_key devex/okta-signin-widget test_org_okta_api_key OKTA_CLIENT_TOKEN

# Build
if ! yarn workspace v3 build:release; then
echo "build failed! Exiting..."
exit ${TEST_FAILURE}
fi

if ! setup_service node v14.18.2 &> /dev/null; then
echo "Failed to install node"
exit ${FAILED_SETUP}
fi

# Run tests
export DISABLE_CSP=1
export CDN_ONLY=1
export BUNDLE="next"
export TARGET="CROSS_BROWSER"
export USE_MIN=1

if ! yarn test:e2e; then
echo "e2e saucelabs test failed! Exiting..."
exit ${PUBLISH_TYPE_AND_RESULT_DIR_BUT_ALWAYS_FAIL}
fi

exit ${PUBLISH_TYPE_AND_RESULT_DIR}
9 changes: 4 additions & 5 deletions scripts/e2e-saucelabs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ export CI=true
source $OKTA_HOME/$REPO/scripts/setup.sh

setup_service java 1.8.222
setup_service google-chrome-stable 89.0.4389.72-1

export RUN_SAUCE_TESTS=true
export RUN_SAUCE_TESTS=ie11,edge
Copy link
Contributor Author

@denysoblohin-okta denysoblohin-okta Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RUN_SAUCE_TESTS can be list of ie11, edge, mobile separated with ,

mobile is not included here (and ine2e-saucelabs-v3 as well) because it's flaky (iPad can show "Let's browse!" message for localhost instead of rendering test app), and there is a separate Bacon test named e2e-saucelabs-mobile that runs tests specially for mobile platforms

Question: do we need edge? Since MS Edge is based on Chromium.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can leave it edge on the list

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean remove ie11 and leave only edge?

export RUN_SAUCE_TESTS=edge

But then we lose ability to easily detect IE11 regressions

export SAUCE_USERNAME=OktaSignInWidget
get_vault_secret_key devex/sauce-labs accessKey SAUCE_ACCESS_KEY
export TEST_SUITE_TYPE="junit"
export TEST_RESULT_FILE_DIR="${REPO}/build2"
echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE}
echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE}

# We use the below OIE enabled org and clients for OIE tests
export WIDGET_TEST_SERVER=https://oie-signin-widget.okta.com
Expand Down Expand Up @@ -39,9 +40,7 @@ export TARGET="CROSS_BROWSER"
export USE_MIN=1
if ! yarn test:e2e; then
echo "e2e saucelabs test failed! Exiting..."
exit ${TEST_FAILURE}
exit ${PUBLISH_TYPE_AND_RESULT_DIR_BUT_ALWAYS_FAIL}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To save screenshots on fail

fi

echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE}
echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE}
exit ${PUBLISH_TYPE_AND_RESULT_DIR}
2 changes: 0 additions & 2 deletions test/e2e/features/widget-flows.feature
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# https://oktainc.atlassian.net/browse/OKTA-545127
@skip(browserName=/internet.*explorer/)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored this test, but it's flaky, so marked all e2e-saucelabs* Bacon tasks as OPTIONAL

Feature: Widget Flows

Background:
Expand Down
41 changes: 31 additions & 10 deletions test/e2e/page-objects/primary-auth-oie.page.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
import { waitForLoad } from '../util/waitUtil';
/* eslint-disable max-len */
import { waitForLoad, waitForText } from '../util/waitUtil';

const { BUNDLE } = process.env;

class PrimaryAuthOIEPage {
identifierFieldSelector = 'input[name="identifier"]';

get enrollProfileButton() { return $('[data-se=enroll]'); }

get forgotPassword() { return $('.siw-main-view.identify-recovery.forgot-password'); }
get forgotPassword() { return $(BUNDLE === 'next' ? 'form[data-se="o-form"]' : '.siw-main-view.identify-recovery.forgot-password'); }
get forgotPasswordButton() { return $('[data-se="forgot-password"]'); }
get unlockButton() {return $('[data-se="unlock"]');}
get nextButton() { return $('[value="Next"]'); }
get signupForm() { return $('.siw-main-view.enroll-profile.registration'); }
get signupForm() { return $(BUNDLE === 'next' ? 'form[data-se="o-form"]' : '.siw-main-view.enroll-profile.registration'); }
get signupLink() { return $('a[data-se="enroll"]'); }
get unlockAccountForm() { return $('.siw-main-view.select-authenticator-unlock-account'); }
get primaryAuthForm() { return $('.siw-main-view.primary-auth'); }
get unlockAccountForm() { return $(BUNDLE === 'next' ? 'form[data-se="o-form"]' : '.siw-main-view.select-authenticator-unlock-account'); }
get primaryAuthForm() { return $(BUNDLE === 'next' ? 'form[data-se="o-form"]' : '.siw-main-view.primary-auth'); }
get identifierField() { return $(this.identifierFieldSelector); }
get passwordField() { return $('input[name="credentials.passcode"]'); }
get submitButton() { return $('input[data-type="save"]'); }
get submitButton() { return $(BUNDLE === 'next' ? 'button[data-se="save"]' : 'input[data-type="save"]'); }
get formTitle() { return $('[data-se="o-form-head"]'); }
get oktaOidcIdPButton() { return $('[data-se="social-auth-general-idp-button"]'); }

async waitForForgotPassword() {
await waitForLoad(this.forgotPassword);
if (BUNDLE === 'next') {
await waitForText(this.formTitle, 'Reset your password');
} else {
await waitForLoad(this.forgotPassword);
}
}

async waitForSubmitButton() {
await waitForLoad(this.submitButton);
}

async waitForPrimaryAuthForm() {
await waitForLoad(this.primaryAuthForm);
if (BUNDLE === 'next') {
await waitForLoad(this.identifierField);
await waitForLoad(this.passwordField);
await waitForLoad(this.submitButton);
} else {
await waitForLoad(this.primaryAuthForm);
}
}

async clickEnrollProfileButton() {
Expand Down Expand Up @@ -66,11 +79,19 @@ class PrimaryAuthOIEPage {
}

async waitForSignupForm() {
await waitForLoad(this.signupForm);
if (BUNDLE === 'next') {
await waitForText(this.formTitle, 'Sign up');
} else {
await waitForLoad(this.signupForm);
}
}

async waitForUnlockAccountForm() {
await waitForLoad(this.unlockAccountForm);
if (BUNDLE === 'next') {
await waitForText(this.formTitle, 'Unlock account');
} else {
await waitForLoad(this.unlockAccountForm);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion test/e2e/page-objects/test-app.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ class TestAppPage {

async setConfig(config) {
await waitForLoad(this.configEditor);
await this.configEditor.then(el => el.setValue(JSON.stringify(config)));
const $configEditor = await this.configEditor;
await $configEditor.setValue(JSON.stringify(config));
}

async getCspErrors() {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const getTask = ({ bundle }) => {
console.log('RUN_FEATURE_TESTS is true, using configuration: cucumber.wdio.conf.ts');
wdioConfig = path.resolve(__dirname, 'cucumber.wdio.conf.ts');
} else if (process.env.RUN_SAUCE_TESTS) {
console.log('RUN_SAUCE_TESTS is true, using configuration: sauce.wdio.conf.ts');
console.log(`RUN_SAUCE_TESTS is ${process.env.RUN_SAUCE_TESTS}, using configuration: sauce.wdio.conf.ts`);
wdioConfig = path.resolve(__dirname, 'sauce.wdio.conf.ts');
} else {
console.log('Using default wdio configuration: wdio.conf.js');
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/sauce.wdio.conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ exports.config = {
path: '/wd/hub',
user: process.env.SAUCE_USERNAME,
key: process.env.SAUCE_ACCESS_KEY,
cucumberOpts: {...conf.cucumberOpts, timeout: 20000},
cucumberOpts: {...conf.cucumberOpts, timeout: 30000},
maxInstances: 1,
waitforTimeout: 15000,
waitforTimeout: 20000,
specs: [
path.resolve(__dirname, 'features/**/widget-flows.feature')
],
Expand Down
12 changes: 8 additions & 4 deletions test/e2e/steps/after.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import TestAppPage from '../page-objects/test-app.page';

// eslint-disable-next-line no-unused-vars
AfterStep(async function (this: ActionContext) {
this.saveScreenshot('afterStep');
await this.saveScreenshot('afterStep');
});

After(deleteUserAndCredentials);
Expand All @@ -41,10 +41,14 @@ After(async function(this: ActionContext) {
}
});

After(() => browser.deleteCookies());

// eslint-disable-next-line no-unused-vars
After(async function(this: ActionContext) {
await TestAppPage.ssoLogout();
if (this.scenario?.gherkinDocument?.feature?.name !== 'Widget Flows') {
await TestAppPage.ssoLogout();
await this.saveScreenshot('ssoLogout');
}
});

After(async () => {
await browser.deleteCookies();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes more sense to move cookies deletion after logout

});
10 changes: 8 additions & 2 deletions test/e2e/steps/before.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Before, BeforeAll } from '@cucumber/cucumber';
import ActionContext from '../support/context';
import { saveScreenshot } from '../support/screenshots';
import type { Capabilities } from '@wdio/types';

// Add support for screenshots
let scenarioCounter = 0;
Expand All @@ -15,9 +16,14 @@ Before(async function(this: ActionContext, scenario) {
this.saveScreenshot = async function(this: ActionContext, fileName: string | undefined) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const scenario = this.scenario!;
const browserName = (browser.requestedCapabilities as Capabilities.Capabilities)?.browserName ?? 'unknown';
const feature = scenario.gherkinDocument.feature?.name;
const step = scenario.pickle.name;
fileName = `${feature}-${scenarioNum}-${++screenshotCounter}-${step}-${fileName}`;
await saveScreenshot(fileName);
fileName = `${browserName}-${feature}-${scenarioNum}-${++screenshotCounter}-${step}-${fileName}`;
try {
await saveScreenshot(fileName);
} catch (e) {
console.error(`Failed to save screenshot ${fileName}: ${e}`);
}
}
});
2 changes: 1 addition & 1 deletion test/e2e/steps/given.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Given(
await TestAppPage.showSignInToGetTokens.click();
break;
}
this.saveScreenshot(`user-opens-login-page-using-${buttonName}`);
await this.saveScreenshot(`user-opens-login-page-using-${buttonName}`);
return await waitForLoad(TestAppPage.widget);
}
);
Expand Down
1 change: 0 additions & 1 deletion test/e2e/steps/then.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ Then(
Then(
/^user sees forgot password form$/,
async function() {
this.saveScreenshot('user-sees-forgot-password-form');
return await PrimaryAuthPage.waitForForgotPassword();
}
);
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/steps/when.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ When(
emailMagicLink = await this.a18nClient!.getEmailMagicLink(this.credentials.profileId!);
}
await browser.url(emailMagicLink);
this.saveScreenshot('click-magic-link');
await this.saveScreenshot('click-magic-link');
}
);

Expand Down
Loading