0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-27 21:39:16 -05:00

fix(console,test): should clear error message and add console integration test (#5081)

* fix(console,test): should clear error message and add console integration test

* refactor(test): refactor code using cls and dcls methods if possible
This commit is contained in:
Darcy Ye 2023-12-11 13:02:33 +08:00 committed by GitHub
parent 08489334dd
commit 9870ddeff0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 13 deletions

View file

@ -32,12 +32,14 @@ function DomainsInput({ className, values, onChange: rawOnChange, error, placeho
const [focusedValueId, setFocusedValueId] = useState<Nullable<string>>(null);
const [currentValue, setCurrentValue] = useState('');
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { setError } = useFormContext<DomainsFormType>();
const { setError, clearErrors } = useFormContext<DomainsFormType>();
const onChange = (values: Option[]) => {
const { values: parsedValues, errorMessage } = domainOptionsParser(values);
if (errorMessage) {
setError('domains', { type: 'custom', message: errorMessage });
} else {
clearErrors('domains');
}
rawOnChange(parsedValues);
};

View file

@ -97,7 +97,6 @@ function Experience({ data, isDeleted, onUpdated, isDarkModeEnabled }: Props) {
watch,
setValue,
setError,
clearErrors,
handleSubmit,
register,
formState: { defaultValues, isDirty, isSubmitting, errors },

View file

@ -4,14 +4,24 @@ import {
expectModalWithTitle,
expectToClickDetailsPageOption,
expectConfirmModalAndAct,
expectToSaveChanges,
waitForToast,
} from '#src/ui-helpers/index.js';
import { expectNavigation, appendPathname } from '#src/utils.js';
import { expectNavigation, appendPathname, dcls, cls } from '#src/utils.js';
import { findModalFooterButton, fillSsoConnectorCreationModal } from './helpers.js';
import { ssoConnectorTestCases } from './sso-connectors-test-cases.js';
await page.setViewport({ width: 1920, height: 1080 });
const emailDomainInputFieldSelector = [
'form',
`${dcls('input')}${cls('multiple')}[role=button]`,
'input',
].join(' ');
const emailDomainErrorMessageSelector = ['form', dcls('field'), dcls('errorMessage')].join(' ');
describe('create SSO connectors', () => {
const logtoConsoleUrl = new URL(logtoConsoleUrlString);
@ -26,7 +36,7 @@ describe('create SSO connectors', () => {
);
await expect(page).toMatchElement(
'div[class$=main] div[class$=headline] div[class$=titleEllipsis]',
[dcls('main'), dcls('headline'), dcls('titleEllipsis')].join(' '),
{
text: 'Enterprise SSO',
}
@ -37,7 +47,7 @@ describe('create SSO connectors', () => {
it('can open create SSO connector modal from table placeholder and create the first SSO connector', async () => {
// When no SSO connector is created, use the create button in placeholder.
await expect(page).toClick('table div[class$=placeholder] button span', {
await expect(page).toClick(['table', dcls('placeholder'), 'button', 'span'].join(' '), {
text: 'Add enterprise connector',
});
@ -57,9 +67,12 @@ describe('create SSO connectors', () => {
await page.waitForNavigation({ waitUntil: 'networkidle0' });
// When there are existing SSO connector(s), use the create button in page header.
await expect(page).toClick('div[class$=main] div[class$=headline] button[type=button] span', {
text: 'Add enterprise connector',
});
await expect(page).toClick(
[dcls('main'), dcls('headline'), 'button[type=button]', 'span'].join(' '),
{
text: 'Add enterprise connector',
}
);
await expectModalWithTitle(page, 'Add enterprise connector');
@ -76,9 +89,12 @@ describe('create SSO connectors', () => {
await page.waitForNavigation({ waitUntil: 'networkidle0' });
// When there are existing SSO connector(s), use the create button in page header.
await expect(page).toClick('div[class$=main] div[class$=headline] button[type=button] span', {
text: 'Add enterprise connector',
});
await expect(page).toClick(
[dcls('main'), dcls('headline'), 'button[type=button]', 'span'].join(' '),
{
text: 'Add enterprise connector',
}
);
await expectModalWithTitle(page, 'Add enterprise connector');
@ -95,7 +111,7 @@ describe('create SSO connectors', () => {
// Error message should be shown.
await expect(page).toMatchElement(
'.ReactModalPortal div[class$=field] div[class$=errorMessage]',
['.ReactModalPortal', dcls('field'), dcls('errorMessage')].join(' '),
{
text: 'Connector name already exists. Please choose a different name.',
}
@ -104,7 +120,7 @@ describe('create SSO connectors', () => {
await expect(findModalFooterButton(true)).resolves.toBeTruthy();
await expect(page).toFill(
'.ReactModalPortal input[type=text][name=connectorName]',
['.ReactModalPortal', 'input[type=text][name=connectorName]'].join(' '),
`${connectorName} (1)`
);
@ -125,6 +141,108 @@ describe('create SSO connectors', () => {
expect(page.url().endsWith('/connection')).toBeTruthy();
});
it("can go to SSO connector's 'SSO Experience' tab", async () => {
// Navigate to "SSO Experience" tab
await expect(page).toClick(['nav', dcls('item'), dcls('link'), 'a'].join(' '), {
text: 'SSO Experience',
});
// Confirm the current path is for "SSO Experience".
expect(page.url().endsWith('/experience')).toBeTruthy();
// Confirm the current tab is "SSO Experience".
await expect(page).toMatchElement(['nav', dcls('item'), dcls('selected'), 'a'].join(' '), {
text: 'SSO Experience',
});
});
it("can configure SSO connectors's 'SSO Experience' GENERAL setup", async () => {
// Expect to see inline notification alert to configure email domain.
await expect(page).toMatchElement(
['form', `${dcls('alert')}${cls('inlineNotification')}`, dcls('content')].join(' '),
{
text: 'Add email domain to guide enterprise users to their identity provider for Single Sign-on.',
}
);
// Configure email domain
await expect(page).toFill(emailDomainInputFieldSelector, 'svhd.io');
// Press enter to add email domain
await page.keyboard.press('Enter');
// Input email domain with invalid format
await expect(page).toFill(emailDomainInputFieldSelector, 'abc');
// Press space to add email domain
await page.keyboard.press('Space');
await expect(page).toMatchElement(emailDomainErrorMessageSelector, {
text: 'Invalid domain format.',
});
// Input public email domain (e.g., 'gmail.com', 'yahoo.com' etc)
await expect(page).toFill(emailDomainInputFieldSelector, 'gmail.com');
// Press tab to add email domain
await page.keyboard.press('Tab');
await expect(page).toMatchElement(emailDomainErrorMessageSelector, {
text: 'Public email domains are not allowed. Invalid domain format.',
});
// Remove last added email domain (which is `gmail.com` in this case). CSS selector can not specify the text content of the component.
await expect(page).toClick(
[
'form',
`${dcls('input')}${cls('multiple')}[role=button]`,
`${dcls('info')}${cls('tag')}:last-of-type`,
'button',
].join(' ')
);
// Error message got updated, since forbidden email domain is removed.
await expect(page).toMatchElement(emailDomainErrorMessageSelector, {
text: 'Invalid domain format.',
});
await expect(page).toFill(emailDomainInputFieldSelector, 'abc');
// Input field blurred to input email domain.
await page.$eval(
// Can not use `emailDomainInputFieldSelector` here since it could break the type inference.
'form div[class*=input][class*=multiple][role=button] input',
(element: HTMLInputElement) => {
element.blur();
}
);
// Does not allow duplicate email domain.
await expect(page).toMatchElement(emailDomainErrorMessageSelector, {
text: 'There are duplicate domains. Invalid domain format.',
});
// Remove last two added email domains (which are two `abc` in this case).
await expect(page).toClick(
[
'form',
`${dcls('input')}${cls('multiple')}[role=button]`,
`${dcls('info')}${cls('tag')}:last-of-type`,
'button',
].join(' ')
);
// Focus on email domain input field component (at this time, the input field is empty).
const inputField = await page.$(emailDomainInputFieldSelector);
await inputField?.focus();
// Should remove the last input email domain with double backspace when the input box is empty.
await inputField?.press('Backspace');
await inputField?.press('Backspace');
// Since incorrect email domains are removed, error message no longer exists.
const errorMessage = await page.$(emailDomainErrorMessageSelector);
expect(errorMessage).toBeNull();
await expectToSaveChanges(page);
await waitForToast(page, { text: 'Saved' });
});
it('can delete an SSO connector from details page', async () => {
// Delete connector
await expectToClickDetailsPageOption(page, 'Delete');