chore(e2e): formatting with prettier (#4385)

* prettier in e2e

* format

* typescript as dev dependency

* ci all, check linting

* resolve liniting issues

* fix wait-on

* fix package-lock.json

Co-authored-by: Elio Bischof <eliobischof@gmail.com>
This commit is contained in:
Max Peintner
2022-09-19 19:49:46 +02:00
committed by GitHub
parent 8505eb4cc9
commit fc4f4096e0
22 changed files with 522 additions and 526 deletions

View File

@@ -1,15 +1,15 @@
import { login, User } from 'support/login/users'
import { login, User } from 'support/login/users';
export interface apiCallProperties {
authHeader: string
mgntBaseURL: string
authHeader: string;
mgntBaseURL: string;
}
export function apiAuth(): Cypress.Chainable<apiCallProperties> {
return login(User.IAMAdminUser, 'Password1!', false, true).then(token => {
return <apiCallProperties>{
authHeader: `Bearer ${token}`,
mgntBaseURL: `${Cypress.env("BACKEND_URL")}/management/v1/`,
}
})
return login(User.IAMAdminUser, 'Password1!', false, true).then((token) => {
return <apiCallProperties>{
authHeader: `Bearer ${token}`,
mgntBaseURL: `${Cypress.env('BACKEND_URL')}/management/v1/`,
};
});
}

View File

@@ -1,89 +1,118 @@
import { apiCallProperties } from "./apiauth"
import { apiCallProperties } from './apiauth';
export function ensureSomethingExists(api: apiCallProperties, searchPath: string, find: (entity: any) => boolean, createPath: string, body: any): Cypress.Chainable<number> {
return searchSomething(api, searchPath, find).then(sRes => {
if (sRes.entity) {
return cy.wrap({
id: sRes.entity.id,
initialSequence: 0
})
}
return cy.request({
method: 'POST',
url: `${api.mgntBaseURL}${createPath}`,
headers: {
Authorization: api.authHeader
},
body: body,
failOnStatusCode: false,
followRedirect: false,
}).then(cRes => {
expect(cRes.status).to.equal(200)
return {
id: cRes.body.id,
initialSequence: sRes.sequence
}
export function ensureSomethingExists(
api: apiCallProperties,
searchPath: string,
find: (entity: any) => boolean,
createPath: string,
body: any,
): Cypress.Chainable<number> {
return searchSomething(api, searchPath, find)
.then((sRes) => {
if (sRes.entity) {
return cy.wrap({
id: sRes.entity.id,
initialSequence: 0,
});
}
return cy
.request({
method: 'POST',
url: `${api.mgntBaseURL}${createPath}`,
headers: {
Authorization: api.authHeader,
},
body: body,
failOnStatusCode: false,
followRedirect: false,
})
}).then((data) => {
awaitDesired(90, (entity) => !!entity, data.initialSequence, api, searchPath, find)
return cy.wrap<number>(data.id)
.then((cRes) => {
expect(cRes.status).to.equal(200);
return {
id: cRes.body.id,
initialSequence: sRes.sequence,
};
});
})
.then((data) => {
awaitDesired(90, (entity) => !!entity, data.initialSequence, api, searchPath, find);
return cy.wrap<number>(data.id);
});
}
export function ensureSomethingDoesntExist(api: apiCallProperties, searchPath: string, find: (entity: any) => boolean, deletePath: (entity: any) => string): Cypress.Chainable<null> {
return searchSomething(api, searchPath, find).then(sRes => {
if (!sRes.entity) {
return cy.wrap(0)
}
return cy.request({
method: 'DELETE',
url: `${api.mgntBaseURL}${deletePath(sRes.entity)}`,
headers: {
Authorization: api.authHeader
},
failOnStatusCode: false
}).then((dRes) => {
expect(dRes.status).to.equal(200)
return sRes.sequence
export function ensureSomethingDoesntExist(
api: apiCallProperties,
searchPath: string,
find: (entity: any) => boolean,
deletePath: (entity: any) => string,
): Cypress.Chainable<null> {
return searchSomething(api, searchPath, find)
.then((sRes) => {
if (!sRes.entity) {
return cy.wrap(0);
}
return cy
.request({
method: 'DELETE',
url: `${api.mgntBaseURL}${deletePath(sRes.entity)}`,
headers: {
Authorization: api.authHeader,
},
failOnStatusCode: false,
})
}).then((initialSequence) => {
awaitDesired(90, (entity) => !entity , initialSequence, api, searchPath, find)
return null
.then((dRes) => {
expect(dRes.status).to.equal(200);
return sRes.sequence;
});
})
.then((initialSequence) => {
awaitDesired(90, (entity) => !entity, initialSequence, api, searchPath, find);
return null;
});
}
type SearchResult = {
entity: any
sequence: number
}
entity: any;
sequence: number;
};
function searchSomething(api: apiCallProperties, searchPath: string, find: (entity: any) => boolean): Cypress.Chainable<SearchResult> {
return cy.request({
method: 'POST',
url: `${api.mgntBaseURL}${searchPath}`,
headers: {
Authorization: api.authHeader
},
}).then(res => {
return {
entity: res.body.result?.find(find) || null,
sequence: res.body.details.processedSequence
}
function searchSomething(
api: apiCallProperties,
searchPath: string,
find: (entity: any) => boolean,
): Cypress.Chainable<SearchResult> {
return cy
.request({
method: 'POST',
url: `${api.mgntBaseURL}${searchPath}`,
headers: {
Authorization: api.authHeader,
},
})
.then((res) => {
return {
entity: res.body.result?.find(find) || null,
sequence: res.body.details.processedSequence,
};
});
}
function awaitDesired(trials: number, expectEntity: (entity: any) => boolean, initialSequence: number, api: apiCallProperties, searchPath: string, find: (entity: any) => boolean) {
searchSomething(api, searchPath, find).then(resp => {
const foundExpectedEntity = expectEntity(resp.entity)
const foundExpectedSequence = resp.sequence > initialSequence
function awaitDesired(
trials: number,
expectEntity: (entity: any) => boolean,
initialSequence: number,
api: apiCallProperties,
searchPath: string,
find: (entity: any) => boolean,
) {
searchSomething(api, searchPath, find).then((resp) => {
const foundExpectedEntity = expectEntity(resp.entity);
const foundExpectedSequence = resp.sequence > initialSequence;
if (!foundExpectedEntity || !foundExpectedSequence) {
expect(trials, `trying ${trials} more times`).to.be.greaterThan(0);
cy.wait(1000)
awaitDesired(trials - 1, expectEntity, initialSequence, api, searchPath, find)
}
})
if (!foundExpectedEntity || !foundExpectedSequence) {
expect(trials, `trying ${trials} more times`).to.be.greaterThan(0);
cy.wait(1000);
awaitDesired(trials - 1, expectEntity, initialSequence, api, searchPath, find);
}
});
}

View File

@@ -1,19 +1,18 @@
import { apiCallProperties } from "./apiauth"
import { apiCallProperties } from './apiauth';
export enum Policy {
Label = "label"
Label = 'label',
}
export function resetPolicy(api: apiCallProperties, policy: Policy) {
cy.request({
method: 'DELETE',
url: `${api.mgntBaseURL}/policies/${policy}`,
headers: {
Authorization: api.authHeader
},
}).then(res => {
expect(res.status).to.equal(200)
return null
})
}
cy.request({
method: 'DELETE',
url: `${api.mgntBaseURL}/policies/${policy}`,
headers: {
Authorization: api.authHeader,
},
}).then((res) => {
expect(res.status).to.equal(200);
return null;
});
}

View File

@@ -1,80 +1,69 @@
import { apiCallProperties } from "./apiauth"
import { ensureSomethingDoesntExist, ensureSomethingExists } from "./ensure"
import { apiCallProperties } from './apiauth';
import { ensureSomethingDoesntExist, ensureSomethingExists } from './ensure';
export function ensureProjectExists(api: apiCallProperties, projectName: string): Cypress.Chainable<number> {
return ensureSomethingExists(
api,
`projects/_search`,
(project: any) => project.name === projectName,
'projects',
{ name: projectName },
)
return ensureSomethingExists(api, `projects/_search`, (project: any) => project.name === projectName, 'projects', {
name: projectName,
});
}
export function ensureProjectDoesntExist(api: apiCallProperties, projectName: string): Cypress.Chainable<null> {
return ensureSomethingDoesntExist(
api,
`projects/_search`,
(project: any) => project.name === projectName,
(project) => `projects/${project.id}`,
)
return ensureSomethingDoesntExist(
api,
`projects/_search`,
(project: any) => project.name === projectName,
(project) => `projects/${project.id}`,
);
}
class ResourceType {
constructor(
public resourcePath: string,
public compareProperty: string,
public identifierProperty: string,
){}
constructor(public resourcePath: string, public compareProperty: string, public identifierProperty: string) {}
}
export const Apps = new ResourceType('apps', 'name', 'id')
export const Roles = new ResourceType('roles', 'key', 'key')
export const Apps = new ResourceType('apps', 'name', 'id');
export const Roles = new ResourceType('roles', 'key', 'key');
//export const Grants = new ResourceType('apps', 'name')
export function ensureProjectResourceDoesntExist(api: apiCallProperties, projectId: number, resourceType: ResourceType, resourceName: string): Cypress.Chainable<null> {
return ensureSomethingDoesntExist(
api,
`projects/${projectId}/${resourceType.resourcePath}/_search`,
(resource: any) => {
return resource[resourceType.compareProperty] === resourceName
},
(resource) => {
return `projects/${projectId}/${resourceType.resourcePath}/${resource[resourceType.identifierProperty]}`
}
)
export function ensureProjectResourceDoesntExist(
api: apiCallProperties,
projectId: number,
resourceType: ResourceType,
resourceName: string,
): Cypress.Chainable<null> {
return ensureSomethingDoesntExist(
api,
`projects/${projectId}/${resourceType.resourcePath}/_search`,
(resource: any) => {
return resource[resourceType.compareProperty] === resourceName;
},
(resource) => {
return `projects/${projectId}/${resourceType.resourcePath}/${resource[resourceType.identifierProperty]}`;
},
);
}
export function ensureApplicationExists(api: apiCallProperties, projectId: number, appName: string): Cypress.Chainable<number> {
return ensureSomethingExists(
api,
`projects/${projectId}/${Apps.resourcePath}/_search`,
(resource: any) => resource.name === appName,
`projects/${projectId}/${Apps.resourcePath}/oidc`,
{
name: appName,
redirectUris: [
'https://e2eredirecturl.org'
],
responseTypes: [
"OIDC_RESPONSE_TYPE_CODE"
],
grantTypes: [
"OIDC_GRANT_TYPE_AUTHORIZATION_CODE"
],
authMethodType: "OIDC_AUTH_METHOD_TYPE_NONE",
postLogoutRedirectUris: [
'https://e2elogoutredirecturl.org'
],
/* "clientId": "129383004379407963@e2eprojectpermission",
export function ensureApplicationExists(
api: apiCallProperties,
projectId: number,
appName: string,
): Cypress.Chainable<number> {
return ensureSomethingExists(
api,
`projects/${projectId}/${Apps.resourcePath}/_search`,
(resource: any) => resource.name === appName,
`projects/${projectId}/${Apps.resourcePath}/oidc`,
{
name: appName,
redirectUris: ['https://e2eredirecturl.org'],
responseTypes: ['OIDC_RESPONSE_TYPE_CODE'],
grantTypes: ['OIDC_GRANT_TYPE_AUTHORIZATION_CODE'],
authMethodType: 'OIDC_AUTH_METHOD_TYPE_NONE',
postLogoutRedirectUris: ['https://e2elogoutredirecturl.org'],
/* "clientId": "129383004379407963@e2eprojectpermission",
"clockSkew": "0s",
"allowedOrigins": [
"https://testurl.org"
]*/
},
)
},
);
}

View File

@@ -1,49 +1,35 @@
import { apiCallProperties } from "./apiauth"
import { ensureSomethingDoesntExist, ensureSomethingExists } from "./ensure"
import { apiCallProperties } from './apiauth';
import { ensureSomethingDoesntExist, ensureSomethingExists } from './ensure';
export function ensureHumanUserExists(api: apiCallProperties, username: string): Cypress.Chainable<number> {
return ensureSomethingExists(
api,
'users/_search',
(user: any) => user.userName === username,
'users/human',
{
user_name: username,
profile: {
first_name: 'e2efirstName',
last_name: 'e2elastName',
},
email: {
email: 'e2e@email.ch',
},
phone: {
phone: '+41 123456789',
},
})
return ensureSomethingExists(api, 'users/_search', (user: any) => user.userName === username, 'users/human', {
user_name: username,
profile: {
first_name: 'e2efirstName',
last_name: 'e2elastName',
},
email: {
email: 'e2e@email.ch',
},
phone: {
phone: '+41 123456789',
},
});
}
export function ensureMachineUserExists(api: apiCallProperties, username: string): Cypress.Chainable<number> {
return ensureSomethingExists(
api,
'users/_search',
(user: any) => user.userName === username,
'users/machine',
{
user_name: username,
name: 'e2emachinename',
description: 'e2emachinedescription',
},
)
return ensureSomethingExists(api, 'users/_search', (user: any) => user.userName === username, 'users/machine', {
user_name: username,
name: 'e2emachinename',
description: 'e2emachinedescription',
});
}
export function ensureUserDoesntExist(api: apiCallProperties, username: string): Cypress.Chainable<null> {
return ensureSomethingDoesntExist(
api,
'users/_search',
(user: any) => user.userName === username,
(user) => `users/${user.id}`
)
return ensureSomethingDoesntExist(
api,
'users/_search',
(user: any) => user.userName === username,
(user) => `users/${user.id}`,
);
}

View File

@@ -2,11 +2,11 @@
namespace Cypress {
interface Chainable {
*/
/**
* Custom command that authenticates a user.
*
* @example cy.consolelogin('hodor', 'hodor1234')
*/
/**
* Custom command that authenticates a user.
*
* @example cy.consolelogin('hodor', 'hodor1234')
*/
/* consolelogin(username: string, password: string): void
}
}
@@ -23,4 +23,4 @@ Cypress.Commands.add('consolelogin', { prevSubject: false }, (username: string,
cy.location('pathname', {timeout: 5 * 1000}).should('eq', '/');
})
})
*/
*/

View File

@@ -14,7 +14,7 @@
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
import './commands';
// Alternatively you can use CommonJS syntax:
// require('./commands')
// require('./commands')

View File

@@ -1,12 +1,10 @@
require('cypress-terminal-report/src/installLogsCollector')();
require('cypress-terminal-report/src/installLogsCollector')();
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
};
//import './commands'

View File

@@ -1,4 +1,4 @@
import { debug } from "console";
import { debug } from 'console';
export enum User {
OrgOwner = 'org_owner',
@@ -23,77 +23,85 @@ export function login(
const loginUrl: string = '/ui/login';
const issuerUrl: string = '/oauth/v2';
return cy.session(
creds.username,
() => {
const cookies = new Map<string, string>();
return cy
.session(
creds.username,
() => {
const cookies = new Map<string, string>();
cy.intercept({
times: 6
}, req => {
req.headers['cookie'] = requestCookies(cookies);
req.continue((res) => {
updateCookies(res.headers['set-cookie'] as string[], cookies);
});
})
cy.intercept(
{
times: 6,
},
(req) => {
req.headers['cookie'] = requestCookies(cookies);
req.continue((res) => {
updateCookies(res.headers['set-cookie'] as string[], cookies);
});
},
);
let userToken: string
cy.intercept({
method: 'POST',
url: `${issuerUrl}/token`,
}, req => {
req.continue(res => {
userToken = res.body["access_token"]}
)
}).as('token')
let userToken: string;
cy.intercept(
{
method: 'POST',
url: `${issuerUrl}/token`,
},
(req) => {
req.continue((res) => {
userToken = res.body['access_token'];
});
},
).as('token');
cy.intercept({
cy.intercept({
method: 'POST',
url: `${loginUrl}/password*`,
times: 1,
}).as('password');
}).as('password');
cy.visit(loginUrl, { retryOnNetworkFailure: true });
cy.visit(loginUrl, { retryOnNetworkFailure: true });
onUsernameScreen ? onUsernameScreen() : null;
cy.get('#loginName').type(creds.username);
cy.get('#submit-button').click();
onUsernameScreen ? onUsernameScreen() : null;
cy.get('#loginName').type(creds.username);
cy.get('#submit-button').click();
onPasswordScreen ? onPasswordScreen() : null;
cy.get('#password').type(creds.password);
cy.get('#submit-button').click();
onPasswordScreen ? onPasswordScreen() : null;
cy.get('#password').type(creds.password);
cy.get('#submit-button').click();
cy.wait('@password').then((interception) => {
if (interception.response.body.indexOf('Multifactor Setup') === -1){
return
}
cy.wait('@password').then((interception) => {
if (interception.response.body.indexOf('Multifactor Setup') === -1) {
return;
}
cy.contains('button', 'skip').click()
cy.get('#change-old-password').type(creds.password)
cy.get('#change-new-password').type(creds.password)
cy.get('#change-password-confirmation').type(creds.password)
cy.contains('button', 'next').click()
cy.contains('button', 'next').click()
})
cy.contains('button', 'skip').click();
cy.get('#change-old-password').type(creds.password);
cy.get('#change-new-password').type(creds.password);
cy.get('#change-password-confirmation').type(creds.password);
cy.contains('button', 'next').click();
cy.contains('button', 'next').click();
});
cy.wait('@token').then(() => {
cy.task('safetoken', {key: creds.username, token: userToken})
})
cy.wait('@token').then(() => {
cy.task('safetoken', { key: creds.username, token: userToken });
});
onAuthenticated ? onAuthenticated() : null;
onAuthenticated ? onAuthenticated() : null;
cy.get("[data-e2e=authenticated-welcome]");
},
{
validate: () => {
if (force) {
throw new Error('clear session');
}
cy.get('[data-e2e=authenticated-welcome]');
},
},
).then(() => {
return cy.task('loadtoken', {key: creds.username})
});
{
validate: () => {
if (force) {
throw new Error('clear session');
}
},
},
)
.then(() => {
return cy.task('loadtoken', { key: creds.username });
});
}
export function loginname(withoutDomain: string, org?: string): string {
@@ -101,10 +109,9 @@ export function loginname(withoutDomain: string, org?: string): string {
}
function credentials(user: User, pw?: string) {
// TODO: ugly
const woDomain = user == User.IAMAdminUser ? User.IAMAdminUser : `${user}_user_name`
const org = Cypress.env('ORGANIZATION') ? Cypress.env('ORGANIZATION') : 'zitadel'
const woDomain = user == User.IAMAdminUser ? User.IAMAdminUser : `${user}_user_name`;
const org = Cypress.env('ORGANIZATION') ? Cypress.env('ORGANIZATION') : 'zitadel';
return {
username: loginname(woDomain, org),