mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
test: add ui tests for webhook management (#3923)
This commit is contained in:
parent
1b57f26533
commit
f38d734e40
3 changed files with 181 additions and 16 deletions
|
@ -1,8 +1,5 @@
|
|||
import {
|
||||
consolePassword,
|
||||
consoleUsername,
|
||||
logtoConsoleUrl as logtoConsoleUrlString,
|
||||
} from '#src/constants.js';
|
||||
import { logtoConsoleUrl as logtoConsoleUrlString } from '#src/constants.js';
|
||||
import { goToAdminConsole } from '#src/ui-helpers/index.js';
|
||||
import {
|
||||
appendPathname,
|
||||
formatPhoneNumberToInternational,
|
||||
|
@ -18,17 +15,7 @@ describe('user management', () => {
|
|||
const logtoConsoleUrl = new URL(logtoConsoleUrlString);
|
||||
|
||||
beforeAll(async () => {
|
||||
await page.goto(logtoConsoleUrl.href);
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' });
|
||||
|
||||
if (page.url() === new URL('sign-in', logtoConsoleUrl).href) {
|
||||
await expect(page).toFillForm('form', {
|
||||
identifier: consoleUsername,
|
||||
password: consolePassword,
|
||||
});
|
||||
await expect(page).toClick('button[name=submit]');
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' });
|
||||
}
|
||||
await goToAdminConsole();
|
||||
});
|
||||
|
||||
it('navigates to user management page on clicking sidebar menu', async () => {
|
||||
|
|
158
packages/integration-tests/src/tests/ui/webhooks.test.ts
Normal file
158
packages/integration-tests/src/tests/ui/webhooks.test.ts
Normal file
|
@ -0,0 +1,158 @@
|
|||
import { logtoConsoleUrl as logtoConsoleUrlString } from '#src/constants.js';
|
||||
import { goToAdminConsole } from '#src/ui-helpers/index.js';
|
||||
import { appendPathname } from '#src/utils.js';
|
||||
|
||||
await page.setViewport({ width: 1280, height: 720 });
|
||||
|
||||
const createWebhookFromWebhooksPage = async () => {
|
||||
await expect(page).toClick('div[class$=main] div[class$=headline] > button');
|
||||
await expect(page).toClick('span[class$=label]', { text: 'Create new account' });
|
||||
await expect(page).toClick('span[class$=label]', { text: 'Sign in' });
|
||||
await expect(page).toFill('input[name=name]', 'hook_name');
|
||||
await expect(page).toFill('input[name=url]', 'https://example.com/webhook');
|
||||
await expect(page).toClick('button[type=submit]');
|
||||
};
|
||||
|
||||
describe('webhooks', () => {
|
||||
const logtoConsoleUrl = new URL(logtoConsoleUrlString);
|
||||
|
||||
beforeAll(async () => {
|
||||
await goToAdminConsole();
|
||||
});
|
||||
|
||||
it('navigates to webhooks page on clicking sidebar menu', async () => {
|
||||
await page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href);
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' });
|
||||
|
||||
await expect(page).toMatchElement(
|
||||
'div[class$=main] div[class$=headline] div[class$=titleEllipsis]',
|
||||
{
|
||||
text: 'Webhooks',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('can create a new webhook', async () => {
|
||||
await page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href);
|
||||
|
||||
await createWebhookFromWebhooksPage();
|
||||
|
||||
// Go to webhook details page
|
||||
await page.waitForSelector('div[class$=header] div[class$=metadata] div[class$=title]');
|
||||
await expect(page).toMatchElement('div[class$=main] div[class$=metadata] div[class$=title]', {
|
||||
text: 'hook_name',
|
||||
});
|
||||
const hookId = await page.$eval(
|
||||
'div[class$=main] div[class$=metadata] div[class$=row] div:first-of-type',
|
||||
(element) => element.textContent
|
||||
);
|
||||
if (hookId) {
|
||||
expect(page.url()).toBe(new URL(`console/webhooks/${hookId}/settings`, logtoConsoleUrl).href);
|
||||
}
|
||||
});
|
||||
|
||||
it('fails to create webhook if no event is provided', async () => {
|
||||
await page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href);
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' });
|
||||
|
||||
await expect(page).toClick('div[class$=main] div[class$=headline] > button');
|
||||
await expect(page).toFill('input[name=name]', 'hook_name');
|
||||
await expect(page).toFill('input[name=url]', 'https://example.com/webhook');
|
||||
await expect(page).toClick('button[type=submit]');
|
||||
await expect(page).toMatchElement('.ReactModalPortal div[class$=errorMessage]', {
|
||||
text: 'You have to select at least one event.',
|
||||
});
|
||||
});
|
||||
|
||||
it('fails to create webhook if endpoint url is not an HTTPS url', async () => {
|
||||
await page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href);
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' });
|
||||
|
||||
await expect(page).toClick('div[class$=main] div[class$=headline] > button');
|
||||
await expect(page).toClick('span[class$=label]', { text: 'Create new account' });
|
||||
await expect(page).toClick('span[class$=label]', { text: 'Sign in' });
|
||||
await expect(page).toFill('input[name=name]', 'hook_name');
|
||||
await expect(page).toFill('input[name=url]', 'http://example.com/webhook');
|
||||
await expect(page).toClick('button[type=submit]');
|
||||
await expect(page).toMatchElement('.ReactModalPortal div[class$=errorMessage]', {
|
||||
text: 'HTTPS format required for security reasons.',
|
||||
});
|
||||
});
|
||||
|
||||
it('can update webhook details', async () => {
|
||||
await page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href);
|
||||
|
||||
await createWebhookFromWebhooksPage();
|
||||
|
||||
await expect(page).toFill('input[name=name]', 'hook_name_updated');
|
||||
await expect(page).toFill('input[name=url]', 'https://example.com/new-webhook');
|
||||
// Wait for the form to be validated
|
||||
await page.waitForTimeout(1000);
|
||||
await expect(page).toClick('form div[class$=actionBar] button:nth-of-type(2)');
|
||||
// Wait for the data to be saved
|
||||
await page.waitForTimeout(1000);
|
||||
const successToastHandle = await page.waitForSelector('div[class$=success]');
|
||||
await expect(successToastHandle).toMatchElement('div[class$=message]', {
|
||||
text: 'Saved',
|
||||
});
|
||||
});
|
||||
|
||||
it('can disable or enable a webhook', async () => {
|
||||
await page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href);
|
||||
await createWebhookFromWebhooksPage();
|
||||
|
||||
// Disable webhook
|
||||
await expect(page).toClick('div[class$=header] >div:nth-of-type(2) button');
|
||||
// Wait for the menu to be opened
|
||||
await page.waitForTimeout(500);
|
||||
await expect(page).toClick(
|
||||
'.ReactModalPortal div[class$=dropdownContainer] div[role=menuitem]:nth-of-type(1)'
|
||||
);
|
||||
await expect(page).toMatchElement('.ReactModalPortal div[class$=content] div[class$=content]', {
|
||||
text: 'Are you sure you want to reactivate this webhook? Doing so will not send HTTP request to endpoint URL.',
|
||||
});
|
||||
await expect(page).toClick('.ReactModalPortal div[class$=footer] button:last-of-type');
|
||||
// Wait for the state to be updated
|
||||
await page.waitForTimeout(500);
|
||||
await expect(page).toMatchElement(
|
||||
'div[class$=header] div[class$=metadata] div:nth-of-type(2) div[class$=outlined] div:nth-of-type(2)',
|
||||
{
|
||||
text: 'Not in use',
|
||||
}
|
||||
);
|
||||
|
||||
// Enable webhook
|
||||
await expect(page).toClick('div[class$=header] >div:nth-of-type(2) button');
|
||||
// Wait for the menu to be opened
|
||||
await page.waitForTimeout(500);
|
||||
await expect(page).toClick(
|
||||
'.ReactModalPortal div[class$=dropdownContainer] div[role=menuitem]:nth-of-type(1)'
|
||||
);
|
||||
// Wait for the state to be updated
|
||||
await page.waitForTimeout(500);
|
||||
const stateDiv = await page.waitForSelector(
|
||||
'div[class$=header] div[class$=metadata] div:nth-of-type(2) div[class$=state]'
|
||||
);
|
||||
expect(stateDiv).toBeTruthy();
|
||||
});
|
||||
|
||||
it('can regenerate signing key for a webhook', async () => {
|
||||
await page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href);
|
||||
await createWebhookFromWebhooksPage();
|
||||
await expect(page).toClick('button[class$=regenerateButton]');
|
||||
|
||||
await expect(page).toMatchElement(
|
||||
'.ReactModalPortal div[class$=content] div[class$=titleEllipsis]',
|
||||
{
|
||||
text: 'Regenerate signing key',
|
||||
}
|
||||
);
|
||||
await expect(page).toClick('.ReactModalPortal div[class$=footer] button:last-of-type');
|
||||
// Wait for the state to be updated
|
||||
await page.waitForTimeout(500);
|
||||
const successToastHandle = await page.waitForSelector('div[class$=success]');
|
||||
await expect(successToastHandle).toMatchElement('div[class$=message]', {
|
||||
text: 'Signing key has been regenerated.',
|
||||
});
|
||||
});
|
||||
});
|
20
packages/integration-tests/src/ui-helpers/index.ts
Normal file
20
packages/integration-tests/src/ui-helpers/index.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import {
|
||||
consolePassword,
|
||||
consoleUsername,
|
||||
logtoConsoleUrl as logtoConsoleUrlString,
|
||||
} from '#src/constants.js';
|
||||
|
||||
export const goToAdminConsole = async () => {
|
||||
const logtoConsoleUrl = new URL(logtoConsoleUrlString);
|
||||
await page.goto(logtoConsoleUrl.href);
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' });
|
||||
|
||||
if (page.url() === new URL('sign-in', logtoConsoleUrl).href) {
|
||||
await expect(page).toFillForm('form', {
|
||||
identifier: consoleUsername,
|
||||
password: consolePassword,
|
||||
});
|
||||
await expect(page).toClick('button[name=submit]');
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' });
|
||||
}
|
||||
};
|
Loading…
Reference in a new issue