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:
Palash 2022-07-13 20:43:36 +05:30 committed by GitHub
parent 5554cce379
commit 64e638fd58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 447 additions and 15 deletions

View File

@ -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"
},

View File

@ -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;

View File

@ -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;

View File

@ -0,0 +1,3 @@
const getVersion = 'version';
export { getVersion };

View File

@ -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
View 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"
}
]
}
]
}

View File

@ -0,0 +1,7 @@
{
"accessJwt": "authtoken",
"accessJwtExpiry": 1656609177,
"refreshJwt": "refreshJwt",
"refreshJwtExpiry": 1659199377,
"userId": "34917776-514b-4b95-a4f5-1a5cc06e34b6"
}

View File

@ -0,0 +1,3 @@
{
"data": "org updated successfully"
}

View File

@ -0,0 +1 @@
{ "data": "user registered successfully" }

View 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"
}

View 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
View 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
View 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';

View 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);
});
});

View 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}`);
});
});

View 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}`);
});
});

View File

@ -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);
});
});

View File

@ -36,6 +36,7 @@
"./commitlint.config.ts",
"./webpack.config.js",
"./webpack.config.prod.js",
"./jest.setup.ts"
"./jest.setup.ts",
"./tests/**.ts",
]
}