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

MEN-7316 - made SAML tests rely on own SAML idp #4447

Merged
merged 4 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions tests/e2e_tests/docker-compose.e2e-tests.enterprise.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '2.3'

services:
mender-gui-tests-runner:
depends_on:
Expand All @@ -16,3 +14,7 @@ services:
- mender-workflows-worker
- mender-create-artifact-worker
- minio

mender-useradm:
environment:
USERADM_BASE_URL: "https://docker.mender.io"
2 changes: 0 additions & 2 deletions tests/e2e_tests/docker-compose.e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '2.3'

services:
mender-gui-tests-runner:
image: mendersoftware/mender-test-containers:gui-e2e-testing
Expand Down
5 changes: 5 additions & 0 deletions tests/e2e_tests/fixtures/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ const test = (process.env.TEST_ENVIRONMENT === 'staging' ? nonCoveredTest : cove
const page = await context.newPage();
await page.goto(`${baseUrl}ui/`);
await isLoggedIn(page);
const isHeaderComplete = await page.getByText(username).isVisible();
if (!isHeaderComplete) {
await page.reload();
await page.waitForSelector(`text=${username}`);
}
await use(page);
await context.storageState({ path: storagePath });
},
Expand Down
28 changes: 28 additions & 0 deletions tests/e2e_tests/fixtures/idp-private-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGrxXmnfGn4NSE
aVhOBJlcba6md6ZpOMLTPncfFGLe1aaQ1Il0B6A5q6+Ra7a6X+dfU0Z66yiTR81y
SUaodZcL/TOAoHeAWCbU0iPyrLlO18cuRHSKDzRRY9m025lW2WQ4iCRBCpkfkjGn
epcxJwUASdhc54jur2ztcmWdN8TDOy5qe+q6oL5SMd+lImUKek1xsL9qL40p6Rx+
JrjQq6nz7uW6TdkWqKYbKpag4n4iqxfLovjomYhy036X4/cmK79/OyPRBEr99aJJ
GoJTVEKDjwihWBgCuXRM5xgdxELOowBD21Jb4EZWtFixqTaXBW0UzY0LqRfsHORq
avBHe7Q9AgMBAAECggEAQBFDYas6uqTAQrZpmDbZcTmZIOriSXnZMR8qcGY1f5+r
Z3ZxoG25F/+pzJ3MPYshY9bJmmdsHRoBQMIqO7Y3b9FFI0wbXNKQKv5cQyu5UZg5
DU1buw0uFLS7Bhvt9ViCfcxAzIxrVgfhZR0d1ea8MRye3U54FGeTG3pRFAJgu4cu
qpLh1c2iB7h/9ookt7tnTMP6Lqse9TPUe0QMqJ5Bkh7U0Ybemp+zCNXm2irFO9MJ
50GaM6Imcsz3TL3vWjnUhB8BVp8aNAAdiOXJ5H0Ut2OgThn+3NIrGVOq04cSfdJM
v3K0XVrG4KWt0UA8U6BKVG1ihaqsZqYImgsVEI3dDQKBgQD6xmNSPmPSildClU7M
YToiHxi0c8dXdjqycek0lrXSzuveUjOzWnQukrzYrSqPRxkJzVRdIdLigKmt3bcN
koj9C1zuse44UYz5hu0iQf24r10wedMtQ9Xs2PSqDS4eIroN860KPiWi6+pjMNdx
/gER9/HScH2jNnSGc7eseLXzTwKBgQDK0tk5QDJPtwJpOgFfAExzwsarV0C8TlcX
Cw8PqOYszvmeBlX2qtFquOJs7Bp/cLY3r3PXNCWVLl0akGqeZZO6ws6Zc7tX0UqW
HYLUB4Ocd1zjYxpmsiHzx72cs0y4twuGP9urDGeYgnbs+djod93GLXIMlEyDddM1
2qYMJj8sswKBgQDplSimTp7EWT92MYS4MkfnyHdGfiFLgkCiPiAub8LknQBukLq/
cJ2PU/a7DHD8DAlya+MM7Jh1icqCvGXpKniW2qKxYuK1aqCZO+hdZIJkKFPw90iQ
fQMiHeOnEafHQilzHWoshD6iRoSH59KFx0ZP6ldA4K7l+68GHXsUF0vDWQKBgFcX
/2tUI8aTQZfJ7rjKugmjhAgjaYry4PbmKsuArYZkQlAXTGalp1N6nNBE+oPq9HQp
BUdN/y12QUic5wupdqxl5q2CQtpM5whbF8jQiTVxFBQYhEfBCk9SYBuf6rwO7gXx
+fQTWZDlxQexqfD5N+RXs3evXsO8nrurbk4dRld9AoGASQmPpm7EFMJL6Ygxvfbi
LwZ+MXtR0nzoPC5HnnIFJvcyWyOxQ6suw4oU3Xn0F+wk55sSvtBdrWce3IR0t+Eh
1ym3xWEe8VoqQVd7r/Yxsz70yRpkfTTZnZoXaybJKMATh47hcF9blpB4Vx5yA+jv
iNHpnWVEw0BpZHCsa7U/658=
-----END PRIVATE KEY-----
21 changes: 21 additions & 0 deletions tests/e2e_tests/fixtures/idp-public-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDfzCCAmegAwIBAgIUDj58mpwrmrIeStpwXvAV3Gc8880wDQYJKoZIhvcNAQEL
BQAwTzELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9zbG8xDTALBgNVBAcMBE9zbG8x
DzANBgNVBAoMBlRlc3RDbzERMA8GA1UEAwwIVGVzdCBJZHAwHhcNMjQwNjExMDgx
NjM2WhcNNDQwNjA2MDgxNjM2WjBPMQswCQYDVQQGEwJOTzENMAsGA1UECAwET3Ns
bzENMAsGA1UEBwwET3NsbzEPMA0GA1UECgwGVGVzdENvMREwDwYDVQQDDAhUZXN0
IElkcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMavFead8afg1IRp
WE4EmVxtrqZ3pmk4wtM+dx8UYt7VppDUiXQHoDmrr5Frtrpf519TRnrrKJNHzXJJ
Rqh1lwv9M4Cgd4BYJtTSI/KsuU7Xxy5EdIoPNFFj2bTbmVbZZDiIJEEKmR+SMad6
lzEnBQBJ2FzniO6vbO1yZZ03xMM7Lmp76rqgvlIx36UiZQp6TXGwv2ovjSnpHH4m
uNCrqfPu5bpN2RaophsqlqDifiKrF8ui+OiZiHLTfpfj9yYrv387I9EESv31okka
glNUQoOPCKFYGAK5dEznGB3EQs6jAEPbUlvgRla0WLGpNpcFbRTNjQupF+wc5Gpq
8Ed7tD0CAwEAAaNTMFEwHQYDVR0OBBYEFA8T69cPPQe7Fqp1Hlhjbxb9K/qBMB8G
A1UdIwQYMBaAFA8T69cPPQe7Fqp1Hlhjbxb9K/qBMA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggEBACVTURxI3j9cOi7mRhdYYXzxodhaRNrK8HdDbq22
oSTu5gokasK12XKgCs21W5IZJka+2ufdnxqzFkt3fAZ7Djptqqq+ngp7G0Un6pEM
8UULK9rFWA05k8szcBWiEHRtmYVZkkMNae3s7uDLvvDOFELAd8zne1ytKHroZfB7
4sZJRXfh/6vJagBKV/TTXn35TjrDVvOAAL9M95l5gbB8RqkHtaYISU6ZYAj6xgY2
Z3di+dQ7N4dtkMLzJ+Vb6PTxGNz6yNWLkdYMEJOh890AozQvLuSdrRoMH5VOcBiU
897G8NnV0i0taHbg5/ObzCElEXNl3F6it/3c7hrlgiTvkZU=
-----END CERTIFICATE-----
13 changes: 11 additions & 2 deletions tests/e2e_tests/integration/00-setup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ import { expect } from '@playwright/test';
import * as fs from 'fs';

import test from '../fixtures/fixtures';
import { baseUrlToDomain, isLoggedIn, login, prepareCookies, startDockerClient, stopDockerClient, tenantTokenRetrieval } from '../utils/commands';
import {
baseUrlToDomain,
isEnterpriseOrStaging,
isLoggedIn,
login,
prepareCookies,
startDockerClient,
stopDockerClient,
tenantTokenRetrieval
} from '../utils/commands';
import { selectors, storagePath, timeouts } from '../utils/constants';

test.describe('Test setup', () => {
Expand Down Expand Up @@ -94,7 +103,7 @@ test.describe('Test setup', () => {

test.describe('enterprise setting features, that happens to start up a docker client', () => {
test('supports tenant token retrieval', async ({ baseUrl, context, environment, password, username }) => {
test.skip(!['enterprise', 'staging'].includes(environment));
test.skip(!isEnterpriseOrStaging(environment));
console.log(`logging in user with username: ${username} and password: ${password}`);
const { token: JWT, userId } = await login(username, password, baseUrl);
const domain = baseUrlToDomain(baseUrl);
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e_tests/integration/01-login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import axios from 'axios';
import * as https from 'https';

import test, { expect } from '../fixtures/fixtures';
import { baseUrlToDomain, isLoggedIn, prepareCookies, processLoginForm } from '../utils/commands';
import { baseUrlToDomain, isEnterpriseOrStaging, isLoggedIn, prepareCookies, processLoginForm } from '../utils/commands';
import { selectors, storagePath, timeouts } from '../utils/constants';

test.describe('Login', () => {
Expand Down Expand Up @@ -68,7 +68,7 @@ test.describe('Login', () => {
});

test('Does not log in without password', async ({ baseUrl, environment, page, username }) => {
test.skip(['enterprise', 'staging'].includes(environment));
test.skip(isEnterpriseOrStaging(environment));
console.log(`logging in user with username: ${username} and without a password`);
await page.goto(`${baseUrl}ui/`);
// enter valid username and invalid password
Expand Down
9 changes: 7 additions & 2 deletions tests/e2e_tests/integration/03-files.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import https from 'https';
import md5 from 'md5';

import test, { expect } from '../fixtures/fixtures';
import { getTokenFromStorage, tagRelease } from '../utils/commands';
import { getTokenFromStorage, isEnterpriseOrStaging, tagRelease } from '../utils/commands';
import { releaseTag, selectors, storagePath, timeouts } from '../utils/constants';

dayjs.extend(isBetween);
Expand All @@ -41,6 +41,10 @@ test.describe('Files', () => {
});

test('allows artifact generation', async ({ baseUrl, loggedInPage: page }) => {
const hasTaggedRelease = await page.getByText(/customRelease/i).isVisible();
if (hasTaggedRelease) {
return;
}
const releaseName = 'terminalImage';
const uploadButton = await page.getByRole('button', { name: /upload/i });
await uploadButton.click();
Expand All @@ -56,6 +60,7 @@ test.describe('Files', () => {
const token = await getTokenFromStorage(baseUrl);
await tagRelease(releaseName, 'customRelease', baseUrl, token);
await page.waitForTimeout(timeouts.oneSecond); // some extra time for the release to be tagged in the backend
await page.keyboard.press('Escape');
await page.click(`.leftNav :text('Releases')`);
expect(await page.getByText(/customRelease/i)).toBeVisible();
});
Expand Down Expand Up @@ -189,7 +194,7 @@ test.describe('Files', () => {

test('allows file transfer', async ({ browserName, environment, loggedInPage: page }) => {
// TODO adjust test to better work with webkit, for now it should be good enough to assume file transfers work there too if the remote terminal works
test.skip(!['enterprise', 'staging'].includes(environment) || ['webkit'].includes(browserName));
test.skip(!isEnterpriseOrStaging(environment) || ['webkit'].includes(browserName));
await page.click(`.leftNav :text('Devices')`);
await page.click(`${selectors.deviceListItem} div:last-child`);
await page.click(`text=/troubleshooting/i`);
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e_tests/integration/05-deviceDetails.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import * as path from 'path';

import test, { expect } from '../fixtures/fixtures';
import { compareImages } from '../utils/commands';
import { compareImages, isEnterpriseOrStaging } from '../utils/commands';
import { selectors, storagePath, timeouts } from '../utils/constants';

const terminalReferenceFileMap = {
Expand Down Expand Up @@ -70,7 +70,7 @@ test.describe('Device details', () => {
});

test('can be filtered into non-existence', async ({ environment, loggedInPage: page }) => {
test.skip(!['enterprise', 'staging'].includes(environment), 'not available in OS');
test.skip(!isEnterpriseOrStaging(environment), 'not available in OS');
test.setTimeout(2 * timeouts.fifteenSeconds);
await page.click(`.leftNav :text('Devices')`);
await page.getByRole('button', { name: /filters/i }).click();
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e_tests/integration/06-auditlogs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ import * as path from 'path';
import * as readline from 'readline';

import test, { expect } from '../fixtures/fixtures';
import { compareImages } from '../utils/commands';
import { compareImages, isEnterpriseOrStaging } from '../utils/commands';
import { selectors, storagePath, timeouts } from '../utils/constants';

test.describe('Auditlogs', () => {
test.use({ storageState: storagePath });

const secret = 'super secret something text';
test('will track remote terminal sessions', async ({ environment, loggedInPage: page }) => {
test.skip(!['enterprise', 'staging'].includes(environment));
test.skip(!isEnterpriseOrStaging(environment));
await page.click(`.leftNav :text('Devices')`);
await page.click(`${selectors.deviceListItem} div:last-child`);
await page.click(`text=/troubleshooting/i`);
Expand Down
99 changes: 51 additions & 48 deletions tests/e2e_tests/integration/07-saml.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,46 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import axios from 'axios';
import * as fs from 'fs';
import * as https from 'https';
import dns from 'node:dns';
import * as https from 'node:https';

import test, { expect } from '../fixtures/fixtures';
import { getTokenFromStorage, isLoggedIn } from '../utils/commands';
import { getTokenFromStorage, isEnterpriseOrStaging, isLoggedIn, startIdpServer } from '../utils/commands';
import { storagePath, timeouts } from '../utils/constants';

dns.setDefaultResultOrder('ipv4first');

const samlSettings = {
credentials: {
chromium: { login: 'morty', password: 'panic', email: 'msmith@samltest.id' },
firefox: { login: 'rick', password: 'psych', email: 'rsanchez@samltest.id' },
webkit: { login: 'sheldon', password: 'bazinga', email: 'scooper@samltest.id' }
chromium: 'saml.jackson@example.com',
firefox: 'sam.l.jackson@example.com',
webkit: 'samu.l.jackson@example.com'
},
idp_url: 'https://samltest.id/saml/idp'
idpUrl: 'http://localhost:7000/metadata'
};

const httpsAgent = new https.Agent({ rejectUnauthorized: false });
const defaultHeaders = { 'Content-Type': 'application/json' };

let acsUrl = '';
let metadataLocation = '';

test.describe('SAML Login via sso/id/login', () => {
test.describe.configure({ mode: 'serial' });
test.use({ storageState: storagePath });
test.afterAll(async ({ environment, baseUrl, browserName }, testInfo) => {
if (testInfo.status === 'skipped' || environment !== 'staging') {
if (testInfo.status === 'skipped' || !isEnterpriseOrStaging(environment)) {
return;
}
const token = await getTokenFromStorage(baseUrl);
const requestInfo = { headers: { ...defaultHeaders, Authorization: `Bearer ${token}` }, httpsAgent, method: 'GET' };
console.log(`Finished ${testInfo.title} with status ${testInfo.status}. Cleaning up.`);
const response = await axios({
...requestInfo,
url: `${baseUrl}api/management/v1/useradm/users?email=${encodeURIComponent(samlSettings.credentials[browserName].email)}`
url: `${baseUrl}api/management/v1/useradm/users?email=${encodeURIComponent(samlSettings.credentials[browserName])}`
});
if (response.status >= 300 || !response.data.length) {
console.log(`${samlSettings.credentials[browserName].email} does not exist.`);
console.log(`${samlSettings.credentials[browserName]} does not exist.`);
return;
}
const { id: userId } = response.data[0];
Expand All @@ -55,23 +60,29 @@ test.describe('SAML Login via sso/id/login', () => {
url: `${baseUrl}api/management/v1/useradm/users/${userId}`,
method: 'DELETE'
});
console.log(`removed user ${samlSettings.credentials[browserName].email}.`);
console.log(`removed user ${samlSettings.credentials[browserName]}.`);
});

// Setups the SAML/SSO login with samltest.id Identity Provider
test('Set up SAML', async ({ browserName, environment, baseUrl, loggedInPage: page }) => {
test.skip(environment !== 'staging');
test.skip(!isEnterpriseOrStaging(environment));
// allow a lot of time to enter metadata + then some to handle uploading the config to the external service
test.setTimeout(5 * timeouts.sixtySeconds + timeouts.fifteenSeconds);

const { data: metadata, status } = await axios({ url: samlSettings.idp_url, method: 'GET' });
let idpServer;
startIdpServer({}, server => (idpServer = server));
await page.waitForTimeout(timeouts.oneSecond);
const { data: metadata, status } = await axios({ url: samlSettings.idpUrl, method: 'GET' });
idpServer.close();
expect(status).toBeGreaterThanOrEqual(200);
expect(status).toBeLessThan(300);
await page.goto(`${baseUrl}ui/settings/organization-and-billing`);
const isInitialized = await page.isVisible('text=Entity ID');
if (!isInitialized) {
// Check input[type="checkbox"]
await page.locator('input[type="checkbox"]').check();
await page.getByLabel(/Enable Single Sign-On/i).click();
await page.getByRole('combobox').click();
await page.getByRole('option', { name: 'SAML' }).click();
// Click text=input with the text editor
await page.locator('text=input with the text editor').click();

Expand Down Expand Up @@ -109,48 +120,46 @@ test.describe('SAML Login via sso/id/login', () => {
expect(await page.isVisible(`text=${expectedAcsUrl}`)).toBeTruthy();
const expectedSpMetaUrl = `${baseUrl}api/management/v1/useradm/sso/sp/metadata/${metadataId}`;
expect(await page.isVisible(`text=${expectedSpMetaUrl}`)).toBeTruthy();
acsUrl = expectedAcsUrl;
metadataLocation = expectedSpMetaUrl;

const { data: spMetadata, status: spDataStatus } = await axios({ ...requestInfo, url: expectedSpMetaUrl });
expect(spDataStatus).toBeGreaterThanOrEqual(200);
expect(spDataStatus).toBeLessThan(300);

const serviceProviderMetadata = spMetadata.replaceAll('Signed="true"', 'Signed="false"');
fs.writeFileSync('fixtures/service_provider_metadata.xml', serviceProviderMetadata);

await page.goto('https://samltest.id/upload.php');
await page.waitForSelector('text=Metadata Upload Form');
await page.locator('input[type="file"]').setInputFiles('fixtures/service_provider_metadata.xml');
await page.getByRole('button', { name: /upload/i }).click();
await expect(page).toHaveURL('https://samltest.id/upload.php');
await page.waitForSelector('text=We now trust you');
expect(spMetadata).toContain('SPSSODescriptor');
idpServer.close();
await page.waitForTimeout(timeouts.oneSecond);
});

// Creates a user with login that matches Identity privder (samltest.id) user email
test('Creates a user without a password', async ({ environment, browserName, baseUrl, loggedInPage: page }) => {
test.skip(environment !== 'staging');
test('Creates a user without a password', async ({ environment, baseUrl, browserName, loggedInPage: page }) => {
test.skip(!isEnterpriseOrStaging(environment));
await page.goto(`${baseUrl}ui/settings/user-management`);
const userExists = await page.isVisible(`text=${samlSettings.credentials[browserName].email}`);
const userExists = await page.isVisible(`text=${samlSettings.credentials[browserName]}`);
if (userExists) {
console.log(`${samlSettings.credentials[browserName].email} already exists.`);
console.log(`${samlSettings.credentials[browserName]} already exists.`);
return;
}
await page.getByRole('button', { name: /new user/i }).click();
await page.getByPlaceholder(/Email/i).click();
await page.getByPlaceholder(/Email/i).fill(samlSettings.credentials[browserName].email);
await page.getByPlaceholder(/Email/i).fill(samlSettings.credentials[browserName]);
// Click text=Create user
await page.locator('text=Create user').click();
await page.getByRole('button', { name: /Create user/i }).click();
await page.screenshot({ path: './test-results/user-created.png' });
await page.waitForSelector('text=The user was created successfully.');
console.log(`${samlSettings.credentials[browserName].email} created.`);
});

// This test calls auth/sso/${id}/login, where id is the id of the identity provider
// and verifies that login is successful.
test('User can login via sso/login endpoint', async ({ environment, browserName, baseUrl, browser, loggedInPage }) => {
test.skip(environment !== 'staging');
test('User can login via sso/login endpoint', async ({ environment, baseUrl, browser, browserName, loggedInPage }) => {
test.skip(!isEnterpriseOrStaging(environment));
test.setTimeout(3 * timeouts.fifteenSeconds);

await loggedInPage.goto(`${baseUrl}ui/settings/organization-and-billing`);
let idpServer;
startIdpServer({ acsUrl, metadataLocation }, server => (idpServer = server));
await loggedInPage.waitForTimeout(timeouts.oneSecond);
await loggedInPage.goto(`${baseUrl}ui/help`);
await loggedInPage.goto(`${baseUrl}ui/settings`);
await loggedInPage.getByText(/organization/i).click();
await loggedInPage.waitForSelector('text=View metadata in the text editor', { timeout: timeouts.tenSeconds });
let loginUrl = '';
let loginThing = await loggedInPage.locator('*:below(:text("Start URL"))').first();
Expand All @@ -159,27 +168,21 @@ test.describe('SAML Login via sso/id/login', () => {
loginThing = await loggedInPage.locator(':text("Start URL") + *').first();
loginUrl = await loginThing.innerText();
}
console.log(`logging in via ${loginUrl} (credentials set:${browserName})`);
console.log(`logging in via ${loginUrl} (using: ${samlSettings.credentials[browserName]})`);
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(loginUrl);
// This screenshot saves the view right after the first redirection
await page.screenshot({ path: './test-results/saml-redirected.png' });

// fill login info
await page.fill('label:has-text("username")', samlSettings.credentials[browserName].login);
await page.fill('label:has-text("password")', samlSettings.credentials[browserName].password);

// Click button:has-text("Login")
await page.locator('button:has-text("Login")').click();
await page.waitForSelector('text=Accept');
// This screen shot saves the summary of the data that will be sent in assertion
await page.screenshot({ path: './test-results/saml-logging-in.png' });

// Click text=Accept
await page.locator('text=Accept').click();
await page.getByLabel(/Subject NameID/i).clear();
await page.getByLabel(/Subject NameID/i).fill(samlSettings.credentials[browserName]);
await page.getByLabel(/E-Mail Address/i).clear();
await page.getByLabel(/E-Mail Address/i).fill(samlSettings.credentials[browserName]);
await page.getByRole('button', { name: /sign in/i }).click();
// confirm we have logged in successfully
await page.screenshot({ path: './test-results/saml-logging-in-accept.png' });
await isLoggedIn(page);
idpServer.close();
});
});
Loading
Loading