mirror of https://github.com/boxyhq/jackson.git
Compare commits
3 Commits
668a1ba499
...
9943a06ace
Author | SHA1 | Date |
---|---|---|
Aswin V | 9943a06ace | |
Deepak Prabhakara | f08025cc31 | |
Deepak Prabhakara | 63baf12a38 |
|
@ -111,7 +111,7 @@ jobs:
|
|||
ports:
|
||||
- '8000:8000'
|
||||
mocksaml:
|
||||
image: boxyhq/mock-saml:1.2.0
|
||||
image: boxyhq/mock-saml:1.3.9
|
||||
ports:
|
||||
- 4000:4000
|
||||
env:
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export { Portal } from './portal';
|
||||
export { SSOPage } from './sso-page';
|
|
@ -0,0 +1,20 @@
|
|||
import { Locator, Page, expect } from '@playwright/test';
|
||||
|
||||
export class Portal {
|
||||
userAvatarLocator: Locator;
|
||||
constructor(public readonly page: Page) {
|
||||
this.userAvatarLocator = this.page.getByTestId('user-avatar');
|
||||
}
|
||||
|
||||
async doCredentialsLogin() {
|
||||
await this.page.goto('/admin/auth/login');
|
||||
await this.page.getByPlaceholder('Email').fill('super@boxyhq.com');
|
||||
await this.page.getByPlaceholder('Password').fill('999login');
|
||||
await this.page.getByRole('button', { name: 'Sign In' }).click();
|
||||
}
|
||||
|
||||
async isLoggedIn() {
|
||||
// assert login state
|
||||
await expect(this.userAvatarLocator).toBeVisible();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
import type { Page, Locator } from '@playwright/test';
|
||||
import { adminPortalSSODefaults } from '@lib/env';
|
||||
|
||||
const ADMIN_PORTAL_TENANT = adminPortalSSODefaults.tenant;
|
||||
const ADMIN_PORTAL_PRODUCT = adminPortalSSODefaults.product;
|
||||
|
||||
const MOCKSAML_ORIGIN = process.env.MOCKSAML_ORIGIN || 'https://mocksaml.com';
|
||||
const MOCKSAML_SIGNIN_BUTTON_NAME = 'Sign In';
|
||||
|
||||
const MOCKLAB_ORIGIN = 'https://oauth.wiremockapi.cloud';
|
||||
const MOCKLAB_CLIENT_ID = 'mocklab_oauth2';
|
||||
const MOCKLAB_CLIENT_SECRET = 'mocklab_secret';
|
||||
const MOCKLAB_SIGNIN_BUTTON_NAME = 'Login';
|
||||
const MOCKLAB_DISCOVERY_ENDPOINT = 'https://oauth.wiremockapi.cloud/.well-known/openid-configuration';
|
||||
|
||||
export class SSOPage {
|
||||
private readonly createConnection: Locator;
|
||||
private readonly nameInput: Locator;
|
||||
private readonly tenantInput: Locator;
|
||||
private readonly productInput: Locator;
|
||||
private readonly redirectURLSInput: Locator;
|
||||
private readonly defaultRedirectURLInput: Locator;
|
||||
private readonly metadataUrlInput: Locator;
|
||||
private readonly oidcDiscoveryUrlInput: Locator;
|
||||
private readonly oidcClientIdInput: Locator;
|
||||
private readonly oidcClientSecretInput: Locator;
|
||||
private readonly saveConnection: Locator;
|
||||
private readonly deleteButton: Locator;
|
||||
private readonly confirmButton: Locator;
|
||||
private readonly toggleConnectionStatusCheckbox: Locator;
|
||||
private readonly toggleConnectionStatusLabel: Locator;
|
||||
private connections: string[];
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.connections = [];
|
||||
this.createConnection = this.page.getByTestId('create-connection');
|
||||
this.nameInput = this.page.getByLabel('Connection name (Optional)');
|
||||
this.tenantInput = this.page.getByLabel('Tenant');
|
||||
this.productInput = this.page.getByLabel('Product');
|
||||
this.redirectURLSInput = page
|
||||
.getByRole('group')
|
||||
.filter({ hasText: 'Allowed redirect URLs' })
|
||||
.locator(page.getByRole('textbox').first());
|
||||
this.defaultRedirectURLInput = this.page.getByLabel('Default redirect URL');
|
||||
this.metadataUrlInput = this.page.getByLabel('Metadata URL');
|
||||
this.oidcDiscoveryUrlInput = this.page.getByLabel('Well-known URL of OpenID Provider');
|
||||
this.oidcClientIdInput = this.page.getByLabel('Client ID');
|
||||
this.oidcClientSecretInput = this.page.getByLabel('Client Secret');
|
||||
this.saveConnection = this.page.getByRole('button', { name: /save/i });
|
||||
this.toggleConnectionStatusCheckbox = this.page.getByRole('checkbox', { name: 'Active' });
|
||||
this.toggleConnectionStatusLabel = this.page.locator('label').filter({ hasText: 'Active' });
|
||||
this.deleteButton = this.page.getByRole('button', { name: 'Delete' });
|
||||
this.confirmButton = this.page.getByRole('button', { name: 'Confirm' });
|
||||
}
|
||||
|
||||
async goto() {
|
||||
const url = new URL(this.page.url());
|
||||
if (url.pathname !== '/admin/sso-connection') {
|
||||
await this.page.goto('/admin/sso-connection');
|
||||
}
|
||||
}
|
||||
|
||||
async addSSOConnection({
|
||||
name,
|
||||
type = 'saml',
|
||||
baseURL,
|
||||
}: {
|
||||
name: string;
|
||||
type: 'saml' | 'oidc';
|
||||
baseURL: string;
|
||||
}) {
|
||||
const connectionIndex = this.connections.length + 1;
|
||||
const ssoName = `${name}-${connectionIndex}`;
|
||||
// Find the new connection button and click on it
|
||||
await this.createConnection.click();
|
||||
if (type === 'oidc') {
|
||||
// Toggle connection type to OIDC
|
||||
await this.page.getByLabel('OIDC').check();
|
||||
}
|
||||
// Fill the name for the connection
|
||||
await this.nameInput.fill(ssoName);
|
||||
// Fill the tenant for the connection
|
||||
await this.tenantInput.fill(ADMIN_PORTAL_TENANT);
|
||||
// Fill the product for the connection
|
||||
await this.productInput.fill(ADMIN_PORTAL_PRODUCT);
|
||||
// Fill the Allowed redirect URLs for the connection
|
||||
|
||||
await this.redirectURLSInput.fill(baseURL!);
|
||||
// Fill the default redirect URLs for the connection
|
||||
await this.defaultRedirectURLInput.fill(`${baseURL}/admin/auth/idp-login`);
|
||||
if (type === 'saml') {
|
||||
// Enter the metadata url for mocksaml in the form
|
||||
await this.metadataUrlInput.fill(`${MOCKSAML_ORIGIN}/api/namespace/${ssoName}/saml/metadata`);
|
||||
}
|
||||
if (type === 'oidc') {
|
||||
// Enter the OIDC client credentials for mocklab in the form
|
||||
await this.oidcClientIdInput.fill(`${MOCKLAB_CLIENT_ID}-${connectionIndex}`);
|
||||
await this.oidcClientSecretInput.fill(`${MOCKLAB_CLIENT_SECRET}-${connectionIndex}`);
|
||||
// Enter the OIDC discovery url for mocklab in the form
|
||||
await this.oidcDiscoveryUrlInput.fill(MOCKLAB_DISCOVERY_ENDPOINT);
|
||||
}
|
||||
// submit the form
|
||||
await this.saveConnection.click();
|
||||
this.connections = [...this.connections, ssoName];
|
||||
}
|
||||
|
||||
async gotoEditView(name: string) {
|
||||
await this.goto();
|
||||
const editButton = this.page.getByText(name).locator('xpath=..').getByLabel('Edit');
|
||||
await editButton.click();
|
||||
}
|
||||
|
||||
async toggleConnectionStatus(newStatus: boolean) {
|
||||
const isChecked = await this.toggleConnectionStatusCheckbox.isChecked();
|
||||
if (isChecked && !newStatus) {
|
||||
await this.toggleConnectionStatusLabel.click();
|
||||
await this.confirmButton.click();
|
||||
} else if (!isChecked && newStatus) {
|
||||
await this.toggleConnectionStatusLabel.click();
|
||||
await this.confirmButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
async updateSSOConnection({ name, url, newStatus }: { name: string; url: string; newStatus?: boolean }) {
|
||||
await this.gotoEditView(name);
|
||||
await this.redirectURLSInput.fill(url);
|
||||
await this.saveConnection.click();
|
||||
if (typeof newStatus === 'boolean') {
|
||||
await this.gotoEditView(name);
|
||||
await this.toggleConnectionStatus(newStatus);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteSSOConnection(name: string) {
|
||||
await this.gotoEditView(name);
|
||||
// click the delete and confirm deletion
|
||||
await this.deleteButton.click();
|
||||
await this.confirmButton.click();
|
||||
}
|
||||
|
||||
async deleteAllSSOConnections() {
|
||||
let _connection;
|
||||
while ((_connection = this.connections.shift())) {
|
||||
await this.deleteSSOConnection(_connection);
|
||||
}
|
||||
}
|
||||
|
||||
async logout() {
|
||||
const userAvatarLocator = this.page.getByTestId('user-avatar');
|
||||
// Logout from the magic link authentication
|
||||
await userAvatarLocator.click();
|
||||
await this.page.getByTestId('logout').click();
|
||||
}
|
||||
|
||||
async signInWithSSO() {
|
||||
await this.page.getByTestId('sso-login-button').click();
|
||||
}
|
||||
|
||||
async selectIdP(name: string) {
|
||||
const idpSelectionTitle = 'Select an Identity Provider to continue';
|
||||
await this.page.getByText(idpSelectionTitle).waitFor();
|
||||
await this.page.getByRole('button', { name }).click();
|
||||
}
|
||||
|
||||
async signInWithMockSAML() {
|
||||
// Perform sign in at mocksaml
|
||||
await this.page.waitForURL((url) => url.origin === MOCKSAML_ORIGIN);
|
||||
await this.page.getByPlaceholder('jackson').fill('bob');
|
||||
await this.page.getByRole('button', { name: MOCKSAML_SIGNIN_BUTTON_NAME }).click();
|
||||
}
|
||||
|
||||
async signInWithMockLab() {
|
||||
// Perform sign in at mocklab
|
||||
await this.page.waitForURL((url) => url.origin === MOCKLAB_ORIGIN);
|
||||
await this.page.getByPlaceholder('yours@example.com').fill('bob@oidc.com');
|
||||
await this.page.getByRole('button', { name: MOCKLAB_SIGNIN_BUTTON_NAME }).click();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
import { test as baseTest, expect } from '@playwright/test';
|
||||
import { Portal, SSOPage } from 'e2e/support/fixtures';
|
||||
|
||||
type MyFixtures = {
|
||||
ssoPage: SSOPage;
|
||||
portal: Portal;
|
||||
};
|
||||
|
||||
export const test = baseTest.extend<MyFixtures>({
|
||||
portal: async ({ page }, use) => {
|
||||
const portal = new Portal(page);
|
||||
await use(portal);
|
||||
},
|
||||
ssoPage: async ({ page, portal }, use) => {
|
||||
const ssoPage = new SSOPage(page);
|
||||
await ssoPage.goto();
|
||||
await use(ssoPage);
|
||||
await portal.doCredentialsLogin();
|
||||
await portal.isLoggedIn();
|
||||
await ssoPage.deleteAllSSOConnections();
|
||||
},
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + SAML provider + wrong redirectUrl', async ({ ssoPage, page, baseURL }, testInfo) => {
|
||||
const ssoName = `saml-${testInfo.workerIndex}`;
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
|
||||
// check if the first added connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
|
||||
await ssoPage.updateSSOConnection({
|
||||
name: `${ssoName}-1`,
|
||||
url: 'https://invalid-url.com',
|
||||
});
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
await ssoPage.signInWithSSO();
|
||||
// Wait for browser to redirect to error page
|
||||
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
|
||||
// Assert error text
|
||||
await expect(page.getByText(`SSO error: Redirect URL is not allowed.`)).toBeVisible();
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + SAML provider + inactive connection', async ({ ssoPage, page, baseURL }, testInfo) => {
|
||||
const ssoName = `saml-${testInfo.workerIndex}`;
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
|
||||
// check if the first added connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
|
||||
await ssoPage.updateSSOConnection({
|
||||
name: `${ssoName}-1`,
|
||||
url: baseURL!,
|
||||
newStatus: false,
|
||||
});
|
||||
// Confirm connection label inactive is displayed
|
||||
await expect(
|
||||
page.getByText(`${ssoName}-1`).locator('xpath=..').getByRole('cell', { name: 'Inactive', exact: true })
|
||||
).toBeVisible();
|
||||
// Logout and try to sign in with connection
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
await ssoPage.signInWithSSO();
|
||||
// Wait for browser to redirect to error page
|
||||
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
|
||||
// Assert error text
|
||||
await expect(
|
||||
page.getByText('SSO error: SSO connection is deactivated. Please contact your administrator.')
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + OIDC provider + wrong redirectUrl', async ({ ssoPage, page, baseURL }, testInfo) => {
|
||||
const ssoName = `oidc-${testInfo.workerIndex}`;
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
|
||||
// check if the oidc connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
|
||||
await ssoPage.updateSSOConnection({
|
||||
name: `${ssoName}-1`,
|
||||
url: 'https://invalid-url.com',
|
||||
});
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
await ssoPage.signInWithSSO();
|
||||
// Wait for browser to redirect to error page
|
||||
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
|
||||
// Assert error text
|
||||
await expect(page.getByText('SSO error: Redirect URL is not allowed.')).toBeVisible();
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + OIDC provider + inactive connection', async ({ ssoPage, page, baseURL }, testInfo) => {
|
||||
const ssoName = `oidc-${testInfo.workerIndex}`;
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
|
||||
// check if the oidc connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
|
||||
await ssoPage.updateSSOConnection({
|
||||
name: `${ssoName}-1`,
|
||||
url: baseURL!,
|
||||
newStatus: false,
|
||||
});
|
||||
// Confirm connection label inactive is displayed
|
||||
await expect(
|
||||
page.getByText(`${ssoName}-1`).locator('xpath=..').getByRole('cell', { name: 'Inactive', exact: true })
|
||||
).toBeVisible();
|
||||
// Logout and try to sign in with connection
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
await ssoPage.signInWithSSO();
|
||||
// Wait for browser to redirect to error page
|
||||
await page.waitForURL((url) => url.origin === baseURL && url.pathname === '/error');
|
||||
// Assert error text
|
||||
await expect(
|
||||
page.getByText('SSO error: SSO connection is deactivated. Please contact your administrator.')
|
||||
).toBeVisible();
|
||||
});
|
|
@ -0,0 +1,57 @@
|
|||
import { test as baseTest, expect } from '@playwright/test';
|
||||
import { Portal, SSOPage } from 'e2e/support/fixtures';
|
||||
|
||||
type MyFixtures = {
|
||||
ssoPage: SSOPage;
|
||||
portal: Portal;
|
||||
};
|
||||
|
||||
export const test = baseTest.extend<MyFixtures>({
|
||||
ssoPage: async ({ page, baseURL }, use, testInfo) => {
|
||||
const ssoPage = new SSOPage(page);
|
||||
const ssoName = `oidc-${testInfo.workerIndex}`;
|
||||
await ssoPage.goto();
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
|
||||
await use(ssoPage);
|
||||
await ssoPage.deleteAllSSOConnections();
|
||||
},
|
||||
portal: async ({ page }, use) => {
|
||||
const portal = new Portal(page);
|
||||
await use(portal);
|
||||
},
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + OIDC provider', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
|
||||
// check if the first added connection appears in the connection list
|
||||
await expect(page.getByText(`oidc-${testInfo.workerIndex}-1`)).toBeVisible();
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
await ssoPage.signInWithSSO();
|
||||
// Login using MockLab
|
||||
await ssoPage.signInWithMockLab();
|
||||
// Wait for browser to redirect back to admin portal
|
||||
await page.waitForURL((url) => url.origin === baseURL);
|
||||
// Assert logged in state
|
||||
await portal.isLoggedIn();
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + 2 OIDC providers', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
|
||||
const ssoName = `oidc-${testInfo.workerIndex}`;
|
||||
// check if the first added connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
|
||||
// Add second OIDC connection
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
|
||||
// check if the second added connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-2`)).toBeVisible();
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
// Login using MockLab
|
||||
await ssoPage.signInWithSSO();
|
||||
// Select IdP from selection screen
|
||||
await ssoPage.selectIdP(`${ssoName}-2`);
|
||||
await ssoPage.signInWithMockLab();
|
||||
// Wait for browser to redirect back to admin portal
|
||||
await page.waitForURL((url) => url.origin === baseURL);
|
||||
// Assert logged in state
|
||||
await portal.isLoggedIn();
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
import { test as baseTest, expect } from '@playwright/test';
|
||||
import { Portal, SSOPage } from 'e2e/support/fixtures';
|
||||
|
||||
type MyFixtures = {
|
||||
ssoPage: SSOPage;
|
||||
portal: Portal;
|
||||
};
|
||||
|
||||
export const test = baseTest.extend<MyFixtures>({
|
||||
ssoPage: async ({ page, baseURL }, use, testInfo) => {
|
||||
const ssoPage = new SSOPage(page);
|
||||
let ssoName = `saml-${testInfo.workerIndex}`;
|
||||
await ssoPage.goto();
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
|
||||
await ssoPage.goto();
|
||||
ssoName = `oidc-${testInfo.workerIndex}`;
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'oidc', baseURL: baseURL! });
|
||||
await use(ssoPage);
|
||||
await ssoPage.deleteAllSSOConnections();
|
||||
},
|
||||
portal: async ({ page }, use) => {
|
||||
const portal = new Portal(page);
|
||||
await use(portal);
|
||||
},
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + SAML provider + OIDC provider', async ({
|
||||
ssoPage,
|
||||
portal,
|
||||
page,
|
||||
baseURL,
|
||||
}, testInfo) => {
|
||||
// check if the first added connection appears in the connection list
|
||||
await expect(page.getByText(`saml-${testInfo.workerIndex}-1`)).toBeVisible();
|
||||
// check if the second added connection appears in the connection list
|
||||
await expect(page.getByText(`oidc-${testInfo.workerIndex}-2`)).toBeVisible();
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
// Login using MockSAML
|
||||
await ssoPage.signInWithSSO();
|
||||
// Select IdP from selection screen
|
||||
await ssoPage.selectIdP(`saml-${testInfo.workerIndex}-1`);
|
||||
// Login using MockSAML
|
||||
await ssoPage.signInWithMockSAML();
|
||||
// Wait for browser to redirect back to admin portal
|
||||
await page.waitForURL((url) => url.origin === baseURL);
|
||||
// Assert logged in state
|
||||
await portal.isLoggedIn();
|
||||
|
||||
// Logout of SAML login
|
||||
await ssoPage.logout();
|
||||
// Login using MockLab
|
||||
await ssoPage.signInWithSSO();
|
||||
// Select IdP from selection screen
|
||||
await ssoPage.selectIdP(`oidc-${testInfo.workerIndex}-2`);
|
||||
// Login using MockLab
|
||||
await ssoPage.signInWithMockLab();
|
||||
// Wait for browser to redirect back to admin portal
|
||||
await page.waitForURL((url) => url.origin === baseURL);
|
||||
// Assert logged in state
|
||||
await portal.isLoggedIn();
|
||||
});
|
|
@ -0,0 +1,57 @@
|
|||
import { test as baseTest, expect } from '@playwright/test';
|
||||
import { Portal, SSOPage } from 'e2e/support/fixtures';
|
||||
|
||||
type MyFixtures = {
|
||||
ssoPage: SSOPage;
|
||||
portal: Portal;
|
||||
};
|
||||
|
||||
export const test = baseTest.extend<MyFixtures>({
|
||||
ssoPage: async ({ page, baseURL }, use, testInfo) => {
|
||||
const ssoPage = new SSOPage(page);
|
||||
const ssoName = `saml-${testInfo.workerIndex}`;
|
||||
await ssoPage.goto();
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
|
||||
await use(ssoPage);
|
||||
await ssoPage.deleteAllSSOConnections();
|
||||
},
|
||||
portal: async ({ page }, use) => {
|
||||
const portal = new Portal(page);
|
||||
await use(portal);
|
||||
},
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + SAML provider', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
|
||||
// check if the first added connection appears in the connection list
|
||||
await expect(page.getByText(`saml-${testInfo.workerIndex}-1`)).toBeVisible();
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
await ssoPage.signInWithSSO();
|
||||
// Login using MockSAML
|
||||
await ssoPage.signInWithMockSAML();
|
||||
// Wait for browser to redirect back to admin portal
|
||||
await page.waitForURL((url) => url.origin === baseURL);
|
||||
// Assert logged in state
|
||||
await portal.isLoggedIn();
|
||||
});
|
||||
|
||||
test('OAuth2 wrapper + 2 SAML providers', async ({ ssoPage, portal, page, baseURL }, testInfo) => {
|
||||
const ssoName = `saml-${testInfo.workerIndex}`;
|
||||
// check if the first added connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-1`)).toBeVisible();
|
||||
// Add second SAML connection
|
||||
await ssoPage.addSSOConnection({ name: ssoName, type: 'saml', baseURL: baseURL! });
|
||||
// check if the second added connection appears in the connection list
|
||||
await expect(page.getByText(`${ssoName}-2`)).toBeVisible();
|
||||
// Logout of magic link login
|
||||
await ssoPage.logout();
|
||||
// Login using MockSAML
|
||||
await ssoPage.signInWithSSO();
|
||||
// Select IdP from selection screen
|
||||
await ssoPage.selectIdP(`${ssoName}-2`);
|
||||
await ssoPage.signInWithMockSAML();
|
||||
// Wait for browser to redirect back to admin portal
|
||||
await page.waitForURL((url) => url.origin === baseURL);
|
||||
// Assert logged in state
|
||||
await portal.isLoggedIn();
|
||||
});
|
|
@ -75,7 +75,7 @@ test.describe('Admin Portal SSO - SAML', () => {
|
|||
test('delete the SAML SSO connection', async ({ page }) => {
|
||||
await page.goto('/admin/settings');
|
||||
// select the row of the connection list table, then locate the edit button
|
||||
const editButton = page.getByText(TEST_SAML_SSO_CONNECTION_NAME).locator('..').getByLabel('Edit');
|
||||
const editButton = page.getByText(TEST_SAML_SSO_CONNECTION_NAME).locator('xpath=..').getByLabel('Edit');
|
||||
await editButton.click();
|
||||
// click the delete and confirm deletion
|
||||
await page.getByRole('button', { name: 'Delete' }).click();
|
||||
|
@ -138,7 +138,7 @@ test.describe('Admin Portal SSO - OIDC', () => {
|
|||
await page.getByTestId('logout').click();
|
||||
// Click on login with sso button
|
||||
await page.getByTestId('sso-login-button').click();
|
||||
// Perform sign in at mocksaml
|
||||
// Perform sign in at mocklab
|
||||
await page.waitForURL((url) => url.origin === MOCKLAB_ORIGIN);
|
||||
await page.getByPlaceholder('yours@example.com').fill('bob@oidc.com');
|
||||
await page.getByRole('button', { name: MOCKLAB_SIGNIN_BUTTON_NAME }).click();
|
||||
|
|
|
@ -22,4 +22,4 @@ patches:
|
|||
|
||||
images:
|
||||
- name: boxyhq/jackson
|
||||
newTag: 1.23.5
|
||||
newTag: 1.23.7
|
||||
|
|
|
@ -22,4 +22,4 @@ patches:
|
|||
|
||||
images:
|
||||
- name: boxyhq/jackson
|
||||
newTag: 1.23.5
|
||||
newTag: 1.23.7
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "jackson",
|
||||
"version": "1.23.6",
|
||||
"version": "1.23.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "jackson",
|
||||
"version": "1.23.6",
|
||||
"version": "1.23.7",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jackson",
|
||||
"version": "1.23.6",
|
||||
"version": "1.23.7",
|
||||
"private": true,
|
||||
"description": "SAML 2.0 service",
|
||||
"keywords": [
|
||||
|
|
|
@ -22,7 +22,8 @@ const config: PlaywrightTestConfig = {
|
|||
timeout: 60 * 1000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
env: {
|
||||
NODE_ENV: 'test',
|
||||
DEBUG: 'pw:webserver',
|
||||
NEXTAUTH_ADMIN_CREDENTIALS: 'super@boxyhq.com:999login',
|
||||
},
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue