mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 03:39:02 +08:00
test: signup page and login page test are updated (#1351)
* test: sign-up test are updated * test: fail test of version api is added * test: more test case over signup page is added * test: coverage is added * chore: auth json is updated * test: auth token and refresh token test is updated
This commit is contained in:
parent
5554cce379
commit
64e638fd58
@ -13,8 +13,9 @@
|
||||
"jest:coverage": "jest --coverage",
|
||||
"jest:watch": "jest --watch",
|
||||
"postinstall": "is-ci || yarn husky:configure",
|
||||
"playwright": "playwright test --config=./playwright.config.ts",
|
||||
"playwright": "NODE_ENV=testing playwright test --config=./playwright.config.ts",
|
||||
"playwright:local:debug": "PWDEBUG=console yarn playwright --headed --browser=chromium",
|
||||
"playwright:codegen:local":"playwright codegen http://localhost:3301",
|
||||
"husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*",
|
||||
"commitlint": "commitlint --edit $1"
|
||||
},
|
||||
|
@ -16,6 +16,8 @@ const config: PlaywrightTestConfig = {
|
||||
updateSnapshots: 'all',
|
||||
fullyParallel: false,
|
||||
quiet: true,
|
||||
testMatch: ['**/*.spec.ts'],
|
||||
reporter: process.env.CI ? 'github' : 'list',
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
@ -1,14 +1,15 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { getVersion } from 'constants/api';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import { PayloadProps } from 'types/api/user/getVersion';
|
||||
|
||||
const getVersion = async (): Promise<
|
||||
const getVersionApi = async (): Promise<
|
||||
SuccessResponse<PayloadProps> | ErrorResponse
|
||||
> => {
|
||||
try {
|
||||
const response = await axios.get(`/version`);
|
||||
const response = await axios.get(`/${getVersion}`);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
@ -21,4 +22,4 @@ const getVersion = async (): Promise<
|
||||
}
|
||||
};
|
||||
|
||||
export default getVersion;
|
||||
export default getVersionApi;
|
||||
|
3
frontend/src/constants/api.ts
Normal file
3
frontend/src/constants/api.ts
Normal file
@ -0,0 +1,3 @@
|
||||
const getVersion = 'version';
|
||||
|
||||
export { getVersion };
|
@ -262,12 +262,13 @@ function SignUp({ version }: SignUpProps): JSX.Element {
|
||||
setState(updateValue, setConfirmPassword);
|
||||
}}
|
||||
required
|
||||
id="UpdatePassword"
|
||||
id="confirmPassword"
|
||||
/>
|
||||
|
||||
{confirmPasswordError && (
|
||||
<Typography.Paragraph
|
||||
italic
|
||||
id="password-confirm-error"
|
||||
style={{
|
||||
color: '#D89614',
|
||||
marginTop: '0.50rem',
|
||||
@ -340,6 +341,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
|
||||
!organizationName ||
|
||||
!password ||
|
||||
!confirmPassword ||
|
||||
!firstName ||
|
||||
confirmPasswordError ||
|
||||
isPasswordPolicyError
|
||||
}
|
||||
|
38
frontend/tests/auth.json
Normal file
38
frontend/tests/auth.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:3301",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "isSideBarCollapsed",
|
||||
"value": "false"
|
||||
},
|
||||
{
|
||||
"name": "metricsTimeDurations",
|
||||
"value": "{}"
|
||||
},
|
||||
{
|
||||
"name": "i18nextLng",
|
||||
"value": "en-US"
|
||||
},
|
||||
{
|
||||
"name": "reactQueryDevtoolsSortFn",
|
||||
"value": "\"Status > Last Updated\""
|
||||
},
|
||||
{
|
||||
"name": "AUTH_TOKEN",
|
||||
"value": "authtoken"
|
||||
},
|
||||
{
|
||||
"name": "IS_LOGGED_IN",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "REFRESH_AUTH_TOKEN",
|
||||
"value": "refreshJwt"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
7
frontend/tests/fixtures/api/login/200.json
vendored
Normal file
7
frontend/tests/fixtures/api/login/200.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"accessJwt": "authtoken",
|
||||
"accessJwtExpiry": 1656609177,
|
||||
"refreshJwt": "refreshJwt",
|
||||
"refreshJwtExpiry": 1659199377,
|
||||
"userId": "34917776-514b-4b95-a4f5-1a5cc06e34b6"
|
||||
}
|
3
frontend/tests/fixtures/api/organisation/201.json
vendored
Normal file
3
frontend/tests/fixtures/api/organisation/201.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"data": "org updated successfully"
|
||||
}
|
1
frontend/tests/fixtures/api/register/200.json
vendored
Normal file
1
frontend/tests/fixtures/api/register/200.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{ "data": "user registered successfully" }
|
5
frontend/tests/fixtures/api/register/401.json
vendored
Normal file
5
frontend/tests/fixtures/api/register/401.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"status": "error",
|
||||
"errorType": "unauthorized",
|
||||
"error": "You are not allowed to create an account. Please ask your admin to send an invite link"
|
||||
}
|
11
frontend/tests/fixtures/api/userId/200.json
vendored
Normal file
11
frontend/tests/fixtures/api/userId/200.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"createdAt": 1651759141,
|
||||
"email": "prashant@signoz.io",
|
||||
"groupId": "36261238-3214-4ae9-9ef1-661a9f7be5d0",
|
||||
"id": "509fab4a-2578-4f24-8245-1b77b2d6d937",
|
||||
"name": "Prashant",
|
||||
"orgId": "72b4024a-3301-4d90-951e-ee071b96dba5",
|
||||
"organization": "Meta",
|
||||
"profilePictureURL": "",
|
||||
"role": "ADMIN"
|
||||
}
|
43
frontend/tests/fixtures/common.ts
vendored
Normal file
43
frontend/tests/fixtures/common.ts
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
import { Page } from '@playwright/test';
|
||||
import { getVersion } from 'constants/api';
|
||||
|
||||
import loginApiResponse from './api/login/200.json';
|
||||
import updateOrgResponse from './api/organisation/201.json';
|
||||
import successLoginResponse from './api/register/200.json';
|
||||
import userLoginResponse from './api/userId/200.json';
|
||||
import { version } from './constant';
|
||||
|
||||
export const waitForVersionApiSuccess = async (page: Page): Promise<void> => {
|
||||
await page.route(`**/${getVersion}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify({ version }),
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const loginApi = async (page: Page): Promise<void> => {
|
||||
await Promise.all([
|
||||
page.route(`**/register`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(successLoginResponse),
|
||||
}),
|
||||
),
|
||||
page.route(`**/user/${loginApiResponse.userId}`, (route) =>
|
||||
route.fulfill({ status: 200, body: JSON.stringify(userLoginResponse) }),
|
||||
),
|
||||
page.route('**/login', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(loginApiResponse),
|
||||
}),
|
||||
),
|
||||
page.route(`**/org/${userLoginResponse.orgId}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(updateOrgResponse),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
};
|
8
frontend/tests/fixtures/constant.ts
vendored
Normal file
8
frontend/tests/fixtures/constant.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
export const version = 'v1.0.0';
|
||||
export const validemail = 'sample@signoz.io';
|
||||
export const validName = 'Palash';
|
||||
export const validCompanyName = 'Signoz';
|
||||
export const validPassword = 'SamplePassword98@@';
|
||||
|
||||
export const getStartedButtonSelector = 'button[data-attr="signup"]';
|
||||
export const confirmPasswordSelector = '#password-confirm-error';
|
28
frontend/tests/login/fail.spec.ts
Normal file
28
frontend/tests/login/fail.spec.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { getVersion } from 'constants/api';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
test.describe('Version API fail while loading login page', async () => {
|
||||
test('Something went wrong', async ({ page, baseURL }) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
const text = 'Something went wrong';
|
||||
|
||||
await page.route(`**/${getVersion}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 500,
|
||||
body: JSON.stringify({ error: text }),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto(loginPage, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
const el = page.locator(`text=${text}`);
|
||||
|
||||
expect(el).toBeVisible();
|
||||
expect(el).toHaveText(`${text}`);
|
||||
expect(await el.getAttribute('disabled')).toBe(null);
|
||||
});
|
||||
});
|
49
frontend/tests/login/index.spec.ts
Normal file
49
frontend/tests/login/index.spec.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import { waitForVersionApiSuccess } from '../fixtures/common';
|
||||
import { version } from '../fixtures/constant';
|
||||
|
||||
test.describe('Login Page', () => {
|
||||
test.beforeEach(async ({ baseURL, page }) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
await waitForVersionApiSuccess(page);
|
||||
|
||||
await Promise.all([page.goto(loginPage), page.waitForRequest('**/version')]);
|
||||
});
|
||||
|
||||
test('Login Page text should be visible', async ({ page }) => {
|
||||
const signup = 'Monitor your applications. Find what is causing issues.';
|
||||
|
||||
// Click text=Monitor your applications. Find what is causing issues.
|
||||
const el = page.locator(`text=${signup}`);
|
||||
|
||||
expect(el).toBeVisible();
|
||||
});
|
||||
|
||||
test('Create an account button should be present', async ({
|
||||
page,
|
||||
baseURL,
|
||||
}) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
// find button which has text=Create an account
|
||||
const button = page.locator('text=Create an account');
|
||||
|
||||
expect(button).toBeVisible();
|
||||
expect(button).toHaveText('Create an account');
|
||||
expect(await button.getAttribute('disabled')).toBe(null);
|
||||
|
||||
expect(await button.isEnabled()).toBe(true);
|
||||
await expect(page).toHaveURL(loginPage);
|
||||
});
|
||||
|
||||
test('Version of the application when api returns 200', async ({ page }) => {
|
||||
// Click text=SigNoz ${version}
|
||||
const element = page.locator(`text=SigNoz ${version}`);
|
||||
element.isVisible();
|
||||
const text = await element.innerText();
|
||||
expect(text).toBe(`SigNoz ${version}`);
|
||||
});
|
||||
});
|
22
frontend/tests/service/index.spec.ts
Normal file
22
frontend/tests/service/index.spec.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import { loginApi } from '../fixtures/common';
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.describe('Service Page', () => {
|
||||
test.beforeEach(async ({ baseURL, browser }) => {
|
||||
const context = await browser.newContext({ storageState: 'tests/auth.json' });
|
||||
const newPage = await context.newPage();
|
||||
|
||||
await loginApi(newPage);
|
||||
|
||||
await newPage.goto(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
page = newPage;
|
||||
});
|
||||
test('Serice Page is rendered', async ({ baseURL }) => {
|
||||
await expect(page).toHaveURL(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
});
|
||||
});
|
@ -1,17 +1,224 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { expect, Page, PlaywrightTestOptions, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
test('Login Page', async ({ page, baseURL }) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
import { loginApi, waitForVersionApiSuccess } from '../fixtures/common';
|
||||
import {
|
||||
confirmPasswordSelector,
|
||||
getStartedButtonSelector,
|
||||
validCompanyName,
|
||||
validemail,
|
||||
validName,
|
||||
validPassword,
|
||||
} from '../fixtures/constant';
|
||||
|
||||
await page.goto(loginPage, {
|
||||
waitUntil: 'networkidle',
|
||||
const waitForSignUpPageSuccess = async (
|
||||
baseURL: PlaywrightTestOptions['baseURL'],
|
||||
page: Page,
|
||||
): Promise<void> => {
|
||||
const signupPage = `${baseURL}${ROUTES.SIGN_UP}`;
|
||||
|
||||
await page.goto(signupPage);
|
||||
|
||||
await waitForVersionApiSuccess(page);
|
||||
};
|
||||
|
||||
interface FillDetailsInSignUpFormProps {
|
||||
page: Page;
|
||||
email: string;
|
||||
name: string;
|
||||
companyName: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
}
|
||||
|
||||
const fillDetailsInSignUpForm = async ({
|
||||
page,
|
||||
email,
|
||||
name,
|
||||
companyName,
|
||||
password,
|
||||
confirmPassword,
|
||||
}: FillDetailsInSignUpFormProps): Promise<void> => {
|
||||
const emailplaceholder = '[placeholder="name\\@yourcompany\\.com"]';
|
||||
const nameplaceholder = '[placeholder="Your Name"]';
|
||||
const companyPlaceholder = '[placeholder="Your Company"]';
|
||||
const currentPasswordId = '#currentPassword';
|
||||
const confirmPasswordId = '#confirmPassword';
|
||||
|
||||
// Fill [placeholder="name\@yourcompany\.com"]
|
||||
await page.locator(emailplaceholder).fill(email);
|
||||
|
||||
// Fill [placeholder="Your Name"]
|
||||
await page.locator(nameplaceholder).fill(name);
|
||||
|
||||
// Fill [placeholder="Your Company"]
|
||||
await page.locator(companyPlaceholder).fill(companyName);
|
||||
|
||||
// Fill #currentPassword
|
||||
await page.locator(currentPasswordId).fill(password);
|
||||
|
||||
// Fill #confirmPasswordId
|
||||
await page.locator(confirmPasswordId).fill(confirmPassword);
|
||||
};
|
||||
|
||||
test.describe('Sign Up Page', () => {
|
||||
test('When User successfull signup and logged in, he should be redirected to dashboard', async ({
|
||||
page,
|
||||
baseURL,
|
||||
}) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
await waitForVersionApiSuccess(page);
|
||||
|
||||
await Promise.all([page.goto(loginPage), page.waitForRequest('**/version')]);
|
||||
|
||||
const buttonSignupButton = page.locator('text=Create an account');
|
||||
|
||||
await buttonSignupButton.click();
|
||||
|
||||
expect(page).toHaveURL(`${baseURL}${ROUTES.SIGN_UP}`);
|
||||
});
|
||||
|
||||
const signup = 'Monitor your applications. Find what is causing issues.';
|
||||
test('Invite link validation', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
const message =
|
||||
'This will create an admin account. If you are not an admin, please ask your admin for an invite link';
|
||||
|
||||
// Click text=Monitor your applications. Find what is causing issues.
|
||||
const el = page.locator(`text=${signup}`);
|
||||
const messageText = await page.locator(`text=${message}`).innerText();
|
||||
|
||||
expect(el).toBeVisible();
|
||||
expect(messageText).toBe(message);
|
||||
});
|
||||
|
||||
test('User Sign up with valid details', async ({ baseURL, page, context }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(false);
|
||||
|
||||
const buttonText = await gettingStartedButton.evaluate((e) => e.innerHTML);
|
||||
|
||||
expect(buttonText).toMatch(/Get Started/i);
|
||||
|
||||
// Getting Started button is not disabled
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(false);
|
||||
|
||||
await loginApi(page);
|
||||
|
||||
await gettingStartedButton.click();
|
||||
|
||||
await expect(page).toHaveURL(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
await context.storageState({
|
||||
path: 'tests/auth.json',
|
||||
});
|
||||
});
|
||||
|
||||
test('Empty name with valid details', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: '',
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
});
|
||||
|
||||
test('Empty Company name with valid details', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: '',
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
});
|
||||
|
||||
test('Empty Email with valid details', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: '',
|
||||
name: validName,
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
});
|
||||
|
||||
test('Empty Password and confirm password with valid details', async ({
|
||||
baseURL,
|
||||
page,
|
||||
}) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: '',
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: '',
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(false);
|
||||
});
|
||||
|
||||
test('Miss Match Password and confirm password with valid details', async ({
|
||||
baseURL,
|
||||
page,
|
||||
}) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: '',
|
||||
});
|
||||
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -36,6 +36,7 @@
|
||||
"./commitlint.config.ts",
|
||||
"./webpack.config.js",
|
||||
"./webpack.config.prod.js",
|
||||
"./jest.setup.ts"
|
||||
"./jest.setup.ts",
|
||||
"./tests/**.ts",
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user