mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 15:35:10 +00:00
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:
parent
8505eb4cc9
commit
fc4f4096e0
@ -2,3 +2,6 @@
|
||||
|
||||
# grpc output
|
||||
/src/app/proto
|
||||
|
||||
# dev environment
|
||||
src/assets/environment.json
|
||||
|
9
e2e/.prettierignore
Normal file
9
e2e/.prettierignore
Normal file
@ -0,0 +1,9 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# results
|
||||
cypress/screenshots/
|
||||
cypress/videos/
|
||||
cypress/results/
|
5
e2e/.prettierrc.json
Normal file
5
e2e/.prettierrc.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"printWidth": 125,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
@ -1,31 +1,22 @@
|
||||
import {
|
||||
Apps,
|
||||
ensureProjectExists,
|
||||
ensureProjectResourceDoesntExist,
|
||||
} from "../../support/api/projects";
|
||||
import { apiAuth } from "../../support/api/apiauth";
|
||||
import { Apps, ensureProjectExists, ensureProjectResourceDoesntExist } from '../../support/api/projects';
|
||||
import { apiAuth } from '../../support/api/apiauth';
|
||||
|
||||
describe("applications", () => {
|
||||
const testProjectName = "e2eprojectapplication";
|
||||
const testAppName = "e2eappundertest";
|
||||
describe('applications', () => {
|
||||
const testProjectName = 'e2eprojectapplication';
|
||||
const testAppName = 'e2eappundertest';
|
||||
|
||||
beforeEach(`ensure it doesn't exist already`, () => {
|
||||
apiAuth().then((api) => {
|
||||
ensureProjectExists(api, testProjectName).then((projectID) => {
|
||||
ensureProjectResourceDoesntExist(
|
||||
api,
|
||||
projectID,
|
||||
Apps,
|
||||
testAppName
|
||||
).then(() => {
|
||||
ensureProjectResourceDoesntExist(api, projectID, Apps, testAppName).then(() => {
|
||||
cy.visit(`/projects/${projectID}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("add app", () => {
|
||||
cy.get('[data-e2e="app-card-add"]').should("be.visible").click();
|
||||
it('add app', () => {
|
||||
cy.get('[data-e2e="app-card-add"]').should('be.visible').click();
|
||||
// select webapp
|
||||
cy.get('[formcontrolname="name"]').type(testAppName);
|
||||
cy.get('[for="WEB"]').click();
|
||||
@ -34,17 +25,17 @@ describe("applications", () => {
|
||||
cy.get('[for="PKCE"]').click();
|
||||
cy.get('[data-e2e="continue-button-authmethod"]').click();
|
||||
//enter URL
|
||||
cy.get("cnsl-redirect-uris").eq(0).type("https://testurl.org");
|
||||
cy.get("cnsl-redirect-uris").eq(1).type("https://testlogouturl.org");
|
||||
cy.get('cnsl-redirect-uris').eq(0).type('https://testurl.org');
|
||||
cy.get('cnsl-redirect-uris').eq(1).type('https://testlogouturl.org');
|
||||
cy.get('[data-e2e="continue-button-redirecturis"]').click();
|
||||
cy.get('[data-e2e="create-button"]')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get("[id*=overlay]").should("exist");
|
||||
cy.get('[id*=overlay]').should('exist');
|
||||
});
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
//TODO: check client ID/Secret
|
||||
});
|
||||
});
|
||||
|
@ -1,50 +1,39 @@
|
||||
import { apiAuth } from "../../support/api/apiauth";
|
||||
import {
|
||||
ensureHumanUserExists,
|
||||
ensureUserDoesntExist,
|
||||
} from "../../support/api/users";
|
||||
import { loginname } from "../../support/login/users";
|
||||
import { apiAuth } from '../../support/api/apiauth';
|
||||
import { ensureHumanUserExists, ensureUserDoesntExist } from '../../support/api/users';
|
||||
import { loginname } from '../../support/login/users';
|
||||
|
||||
describe("humans", () => {
|
||||
describe('humans', () => {
|
||||
const humansPath = `/users?type=human`;
|
||||
const testHumanUserNameAdd = "e2ehumanusernameadd";
|
||||
const testHumanUserNameRemove = "e2ehumanusernameremove";
|
||||
const testHumanUserNameAdd = 'e2ehumanusernameadd';
|
||||
const testHumanUserNameRemove = 'e2ehumanusernameremove';
|
||||
|
||||
describe("add", () => {
|
||||
describe('add', () => {
|
||||
before(`ensure it doesn't exist already`, () => {
|
||||
apiAuth().then((apiCallProperties) => {
|
||||
ensureUserDoesntExist(apiCallProperties, testHumanUserNameAdd).then(
|
||||
() => {
|
||||
cy.visit(humansPath);
|
||||
}
|
||||
);
|
||||
ensureUserDoesntExist(apiCallProperties, testHumanUserNameAdd).then(() => {
|
||||
cy.visit(humansPath);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should add a user", () => {
|
||||
cy.get('[data-e2e="create-user-button"]')
|
||||
.click();
|
||||
cy.url().should("contain", "users/create");
|
||||
cy.get('[formcontrolname="email"]')
|
||||
.type(loginname("e2ehuman", Cypress.env("ORGANIZATION")));
|
||||
it('should add a user', () => {
|
||||
cy.get('[data-e2e="create-user-button"]').click();
|
||||
cy.url().should('contain', 'users/create');
|
||||
cy.get('[formcontrolname="email"]').type(loginname('e2ehuman', Cypress.env('ORGANIZATION')));
|
||||
//force needed due to the prefilled username prefix
|
||||
cy.get('[formcontrolname="userName"]')
|
||||
.type(testHumanUserNameAdd);
|
||||
cy.get('[formcontrolname="firstName"]')
|
||||
.type("e2ehumanfirstname");
|
||||
cy.get('[formcontrolname="lastName"]')
|
||||
.type("e2ehumanlastname");
|
||||
cy.get('[formcontrolname="phone"]')
|
||||
.type("+41 123456789");
|
||||
cy.get('[formcontrolname="userName"]').type(testHumanUserNameAdd);
|
||||
cy.get('[formcontrolname="firstName"]').type('e2ehumanfirstname');
|
||||
cy.get('[formcontrolname="lastName"]').type('e2ehumanlastname');
|
||||
cy.get('[formcontrolname="phone"]').type('+41 123456789');
|
||||
cy.get('[data-e2e="create-button"]').click();
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe("remove", () => {
|
||||
before("ensure it exists", () => {
|
||||
describe('remove', () => {
|
||||
before('ensure it exists', () => {
|
||||
apiAuth().then((api) => {
|
||||
ensureHumanUserExists(api, testHumanUserNameRemove).then(() => {
|
||||
cy.visit(humansPath);
|
||||
@ -52,19 +41,19 @@ describe("humans", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should delete a human user", () => {
|
||||
cy.contains("tr", testHumanUserNameRemove)
|
||||
it('should delete a human user', () => {
|
||||
cy.contains('tr', testHumanUserNameRemove)
|
||||
// doesn't work, need to force click.
|
||||
// .trigger('mouseover')
|
||||
.find('[data-e2e="enabled-delete-button"]')
|
||||
.click({force: true});
|
||||
.click({ force: true });
|
||||
cy.get('[data-e2e="confirm-dialog-input"]')
|
||||
.focus()
|
||||
.type(loginname(testHumanUserNameRemove, Cypress.env("ORGANIZATION")));
|
||||
.type(loginname(testHumanUserNameRemove, Cypress.env('ORGANIZATION')));
|
||||
cy.get('[data-e2e="confirm-dialog-button"]').click();
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,46 +1,37 @@
|
||||
import { apiAuth } from "../../support/api/apiauth";
|
||||
import {
|
||||
ensureMachineUserExists,
|
||||
ensureUserDoesntExist,
|
||||
} from "../../support/api/users";
|
||||
import { loginname } from "../../support/login/users";
|
||||
import { apiAuth } from '../../support/api/apiauth';
|
||||
import { ensureMachineUserExists, ensureUserDoesntExist } from '../../support/api/users';
|
||||
import { loginname } from '../../support/login/users';
|
||||
|
||||
describe("machines", () => {
|
||||
describe('machines', () => {
|
||||
const machinesPath = `/users?type=machine`;
|
||||
const testMachineUserNameAdd = "e2emachineusernameadd";
|
||||
const testMachineUserNameRemove = "e2emachineusernameremove";
|
||||
const testMachineUserNameAdd = 'e2emachineusernameadd';
|
||||
const testMachineUserNameRemove = 'e2emachineusernameremove';
|
||||
|
||||
describe("add", () => {
|
||||
describe('add', () => {
|
||||
before(`ensure it doesn't exist already`, () => {
|
||||
apiAuth().then((apiCallProperties) => {
|
||||
ensureUserDoesntExist(apiCallProperties, testMachineUserNameAdd).then(
|
||||
() => {
|
||||
cy.visit(machinesPath);
|
||||
}
|
||||
);
|
||||
ensureUserDoesntExist(apiCallProperties, testMachineUserNameAdd).then(() => {
|
||||
cy.visit(machinesPath);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should add a machine", () => {
|
||||
cy.get('[data-e2e="create-user-button"]')
|
||||
.click();
|
||||
cy.url().should("contain", "users/create-machine");
|
||||
it('should add a machine', () => {
|
||||
cy.get('[data-e2e="create-user-button"]').click();
|
||||
cy.url().should('contain', 'users/create-machine');
|
||||
//force needed due to the prefilled username prefix
|
||||
cy.get('[formcontrolname="userName"]')
|
||||
.type(testMachineUserNameAdd);
|
||||
cy.get('[formcontrolname="name"]')
|
||||
.type("e2emachinename");
|
||||
cy.get('[formcontrolname="description"]')
|
||||
.type("e2emachinedescription");
|
||||
cy.get('[formcontrolname="userName"]').type(testMachineUserNameAdd);
|
||||
cy.get('[formcontrolname="name"]').type('e2emachinename');
|
||||
cy.get('[formcontrolname="description"]').type('e2emachinedescription');
|
||||
cy.get('[data-e2e="create-button"]').click();
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe("remove", () => {
|
||||
before("ensure it exists", () => {
|
||||
describe('remove', () => {
|
||||
before('ensure it exists', () => {
|
||||
apiAuth().then((api) => {
|
||||
ensureMachineUserExists(api, testMachineUserNameRemove).then(() => {
|
||||
cy.visit(machinesPath);
|
||||
@ -48,19 +39,19 @@ describe("machines", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should delete a machine", () => {
|
||||
cy.contains("tr", testMachineUserNameRemove)
|
||||
it('should delete a machine', () => {
|
||||
cy.contains('tr', testMachineUserNameRemove)
|
||||
// doesn't work, need to force click.
|
||||
// .trigger('mouseover')
|
||||
.find('[data-e2e="enabled-delete-button"]')
|
||||
.click({force: true});
|
||||
.click({ force: true });
|
||||
cy.get('[data-e2e="confirm-dialog-input"]')
|
||||
.focus()
|
||||
.type(loginname(testMachineUserNameRemove, Cypress.env("ORGANIZATION")));
|
||||
.type(loginname(testMachineUserNameRemove, Cypress.env('ORGANIZATION')));
|
||||
cy.get('[data-e2e="confirm-dialog-button"]').click();
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,49 +1,44 @@
|
||||
import { apiAuth } from "../../support/api/apiauth";
|
||||
import { ensureProjectExists, ensureProjectResourceDoesntExist, Roles } from "../../support/api/projects";
|
||||
import { apiAuth } from '../../support/api/apiauth';
|
||||
import { ensureProjectExists, ensureProjectResourceDoesntExist, Roles } from '../../support/api/projects';
|
||||
|
||||
describe('permissions', () => {
|
||||
const testProjectName = 'e2eprojectpermission';
|
||||
const testAppName = 'e2eapppermission';
|
||||
const testRoleName = 'e2eroleundertestname';
|
||||
const testRoleDisplay = 'e2eroleundertestdisplay';
|
||||
const testRoleGroup = 'e2eroleundertestgroup';
|
||||
const testGrantName = 'e2egrantundertest';
|
||||
|
||||
const testProjectName = 'e2eprojectpermission'
|
||||
const testAppName = 'e2eapppermission'
|
||||
const testRoleName = 'e2eroleundertestname'
|
||||
const testRoleDisplay = 'e2eroleundertestdisplay'
|
||||
const testRoleGroup = 'e2eroleundertestgroup'
|
||||
const testGrantName = 'e2egrantundertest'
|
||||
var projectId: number;
|
||||
|
||||
var projectId: number
|
||||
beforeEach(() => {
|
||||
apiAuth().then((apiCalls) => {
|
||||
ensureProjectExists(apiCalls, testProjectName).then((projId) => {
|
||||
projectId = projId;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('add role', () => {
|
||||
beforeEach(() => {
|
||||
apiAuth().then(apiCalls => {
|
||||
ensureProjectExists(apiCalls, testProjectName).then(projId => {
|
||||
projectId = projId
|
||||
})
|
||||
})
|
||||
})
|
||||
apiAuth().then((api) => {
|
||||
ensureProjectResourceDoesntExist(api, projectId, Roles, testRoleName);
|
||||
cy.visit(`/projects/${projectId}?id=roles`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('add role', () => {
|
||||
beforeEach(()=> {
|
||||
apiAuth().then((api)=> {
|
||||
ensureProjectResourceDoesntExist(api, projectId, Roles, testRoleName)
|
||||
cy.visit(`/projects/${projectId}?id=roles`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should add a role', () => {
|
||||
cy.get('[data-e2e="add-new-role"]').click()
|
||||
cy.get('[formcontrolname="key"]')
|
||||
.type(testRoleName)
|
||||
cy.get('[formcontrolname="displayName"]')
|
||||
.type(testRoleDisplay)
|
||||
cy.get('[formcontrolname="group"]')
|
||||
.type(testRoleGroup)
|
||||
cy.get('[data-e2e="save-button"]')
|
||||
.click()
|
||||
cy.get('.data-e2e-success')
|
||||
cy.wait(200)
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
it('should add a role', () => {
|
||||
cy.get('[data-e2e="add-new-role"]').click();
|
||||
cy.get('[formcontrolname="key"]').type(testRoleName);
|
||||
cy.get('[formcontrolname="displayName"]').type(testRoleDisplay);
|
||||
cy.get('[formcontrolname="group"]').type(testRoleGroup);
|
||||
cy.get('[data-e2e="save-button"]').click();
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
/*
|
||||
|
||||
describe('permissions', () => {
|
||||
@ -112,4 +107,4 @@ describe('permissions', () => {
|
||||
})
|
||||
})
|
||||
|
||||
*/
|
||||
*/
|
||||
|
@ -1,15 +1,12 @@
|
||||
import { apiAuth } from "../../support/api/apiauth";
|
||||
import {
|
||||
ensureProjectDoesntExist,
|
||||
ensureProjectExists,
|
||||
} from "../../support/api/projects";
|
||||
import { apiAuth } from '../../support/api/apiauth';
|
||||
import { ensureProjectDoesntExist, ensureProjectExists } from '../../support/api/projects';
|
||||
|
||||
describe("projects", () => {
|
||||
const testProjectNameCreate = "e2eprojectcreate";
|
||||
const testProjectNameDeleteList = "e2eprojectdeletelist";
|
||||
const testProjectNameDeleteGrid = "e2eprojectdeletegrid";
|
||||
describe('projects', () => {
|
||||
const testProjectNameCreate = 'e2eprojectcreate';
|
||||
const testProjectNameDeleteList = 'e2eprojectdeletelist';
|
||||
const testProjectNameDeleteGrid = 'e2eprojectdeletegrid';
|
||||
|
||||
describe("add project", () => {
|
||||
describe('add project', () => {
|
||||
beforeEach(`ensure it doesn't exist already`, () => {
|
||||
apiAuth().then((api) => {
|
||||
ensureProjectDoesntExist(api, testProjectNameCreate);
|
||||
@ -17,60 +14,56 @@ describe("projects", () => {
|
||||
cy.visit(`/projects`);
|
||||
});
|
||||
|
||||
it("should add a project", () => {
|
||||
cy.get(".add-project-button").click({ force: true });
|
||||
cy.get("input").type(testProjectNameCreate);
|
||||
it('should add a project', () => {
|
||||
cy.get('.add-project-button').click({ force: true });
|
||||
cy.get('input').type(testProjectNameCreate);
|
||||
cy.get('[data-e2e="continue-button"]').click();
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe("remove project", () => {
|
||||
describe("list view", () => {
|
||||
beforeEach("ensure it exists", () => {
|
||||
describe('remove project', () => {
|
||||
describe('list view', () => {
|
||||
beforeEach('ensure it exists', () => {
|
||||
apiAuth().then((api) => {
|
||||
ensureProjectExists(api, testProjectNameDeleteList);
|
||||
});
|
||||
cy.visit(`/projects`);
|
||||
});
|
||||
|
||||
it("removes the project", () => {
|
||||
it('removes the project', () => {
|
||||
cy.get('[data-e2e="toggle-grid"]').click();
|
||||
cy.get('[data-e2e="timestamp"]');
|
||||
cy.contains("tr", testProjectNameDeleteList, { timeout: 1000 })
|
||||
cy.contains('tr', testProjectNameDeleteList, { timeout: 1000 })
|
||||
.find('[data-e2e="delete-project-button"]')
|
||||
.click({ force: true });
|
||||
cy.get('[data-e2e="confirm-dialog-input"]')
|
||||
.focus()
|
||||
.type(testProjectNameDeleteList);
|
||||
cy.get('[data-e2e="confirm-dialog-input"]').focus().type(testProjectNameDeleteList);
|
||||
cy.get('[data-e2e="confirm-dialog-button"]').click();
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe("grid view", () => {
|
||||
beforeEach("ensure it exists", () => {
|
||||
describe('grid view', () => {
|
||||
beforeEach('ensure it exists', () => {
|
||||
apiAuth().then((api) => {
|
||||
ensureProjectExists(api, testProjectNameDeleteGrid);
|
||||
});
|
||||
cy.visit(`/projects`);
|
||||
});
|
||||
|
||||
it("removes the project", () => {
|
||||
it('removes the project', () => {
|
||||
cy.contains('[data-e2e="grid-card"]', testProjectNameDeleteGrid)
|
||||
.find('[data-e2e="delete-project-button"]')
|
||||
.click({force: true});
|
||||
cy.get('[data-e2e="confirm-dialog-input"]')
|
||||
.focus()
|
||||
.type(testProjectNameDeleteGrid);
|
||||
.click({ force: true });
|
||||
cy.get('[data-e2e="confirm-dialog-input"]').focus().type(testProjectNameDeleteGrid);
|
||||
cy.get('[data-e2e="confirm-dialog-button"]').click();
|
||||
cy.get(".data-e2e-success");
|
||||
cy.get('.data-e2e-success');
|
||||
cy.wait(200);
|
||||
cy.get(".data-e2e-failure", { timeout: 0 }).should("not.exist");
|
||||
cy.get('.data-e2e-failure', { timeout: 0 }).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,45 +1,38 @@
|
||||
import { apiAuth } from "../../support/api/apiauth";
|
||||
import { ensureHumanUserExists } from "../../support/api/users";
|
||||
import { login, User } from "../../support/login/users";
|
||||
import { apiAuth } from '../../support/api/apiauth';
|
||||
import { ensureHumanUserExists } from '../../support/api/users';
|
||||
import { login, User } from '../../support/login/users';
|
||||
|
||||
describe("login policy", ()=> {
|
||||
describe('login policy', () => {
|
||||
const orgPath = `/org`;
|
||||
|
||||
const orgPath = `/org`
|
||||
|
||||
;[User.OrgOwner].forEach(user => {
|
||||
|
||||
describe(`as user "${user}"`, () => {
|
||||
|
||||
beforeEach(()=> {
|
||||
login(user)
|
||||
cy.visit(orgPath)
|
||||
// TODO: Why force?
|
||||
cy.contains('[data-e2e="policy-card"]', 'Login Policy').contains('button', 'Modify').click({force: true}) // TODO: select data-e2e
|
||||
apiAuth().then(api => {
|
||||
ensureHumanUserExists(api, User.LoginPolicyUser)
|
||||
})
|
||||
})
|
||||
|
||||
// TODO: verify email
|
||||
|
||||
it.skip(`username and password disallowed`, () => {
|
||||
login(User.LoginPolicyUser, "123abcABC?&*")
|
||||
})
|
||||
it(`registering is allowed`)
|
||||
it(`registering is disallowed`)
|
||||
it(`login by an external IDP is allowed`)
|
||||
it(`login by an external IDP is disallowed`)
|
||||
it(`MFA is forced`)
|
||||
it(`MFA is not forced`)
|
||||
it(`the password reset option is hidden`)
|
||||
it(`the password reset option is shown`)
|
||||
it(`passwordless login is allowed`)
|
||||
it(`passwordless login is disallowed`)
|
||||
describe('identity providers', () => {
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
[User.OrgOwner].forEach((user) => {
|
||||
describe(`as user "${user}"`, () => {
|
||||
beforeEach(() => {
|
||||
login(user);
|
||||
cy.visit(orgPath);
|
||||
// TODO: Why force?
|
||||
cy.contains('[data-e2e="policy-card"]', 'Login Policy').contains('button', 'Modify').click({ force: true }); // TODO: select data-e2e
|
||||
apiAuth().then((api) => {
|
||||
ensureHumanUserExists(api, User.LoginPolicyUser);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: verify email
|
||||
|
||||
it.skip(`username and password disallowed`, () => {
|
||||
login(User.LoginPolicyUser, '123abcABC?&*');
|
||||
});
|
||||
it(`registering is allowed`);
|
||||
it(`registering is disallowed`);
|
||||
it(`login by an external IDP is allowed`);
|
||||
it(`login by an external IDP is disallowed`);
|
||||
it(`MFA is forced`);
|
||||
it(`MFA is not forced`);
|
||||
it(`the password reset option is hidden`);
|
||||
it(`the password reset option is shown`);
|
||||
it(`passwordless login is allowed`);
|
||||
it(`passwordless login is disallowed`);
|
||||
describe('identity providers', () => {});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,34 +1,29 @@
|
||||
import { login, User } from "../../support/login/users";
|
||||
import { login, User } from '../../support/login/users';
|
||||
|
||||
describe("password complexity", ()=> {
|
||||
describe('password complexity', () => {
|
||||
const orgPath = `/org`;
|
||||
const testProjectName = 'e2eproject';
|
||||
|
||||
const orgPath = `/org`
|
||||
const testProjectName = 'e2eproject'
|
||||
|
||||
;[User.OrgOwner].forEach(user => {
|
||||
|
||||
describe(`as user "${user}"`, () => {
|
||||
|
||||
beforeEach(()=> {
|
||||
login(user)
|
||||
cy.visit(orgPath)
|
||||
// TODO: Why force?
|
||||
cy.contains('[data-e2e="policy-card"]', 'Password Complexity').contains('button', 'Modify').click({force: true}) // TODO: select data-e2e
|
||||
})
|
||||
|
||||
// TODO: fix saving password complexity policy bug
|
||||
|
||||
it(`should restrict passwords that don't have the minimal length`)
|
||||
it(`should require passwords to contain a number if option is switched on`)
|
||||
it(`should not require passwords to contain a number if option is switched off`)
|
||||
it(`should require passwords to contain a symbol if option is switched on`)
|
||||
it(`should not require passwords to contain a symbol if option is switched off`)
|
||||
it(`should require passwords to contain a lowercase letter if option is switched on`)
|
||||
it(`should not require passwords to contain a lowercase letter if option is switched off`)
|
||||
it(`should require passwords to contain an uppercase letter if option is switched on`)
|
||||
it(`should not require passwords to contain an uppercase letter if option is switched off`)
|
||||
})
|
||||
})
|
||||
})
|
||||
[User.OrgOwner].forEach((user) => {
|
||||
describe(`as user "${user}"`, () => {
|
||||
beforeEach(() => {
|
||||
login(user);
|
||||
cy.visit(orgPath);
|
||||
// TODO: Why force?
|
||||
cy.contains('[data-e2e="policy-card"]', 'Password Complexity').contains('button', 'Modify').click({ force: true }); // TODO: select data-e2e
|
||||
});
|
||||
|
||||
// TODO: fix saving password complexity policy bug
|
||||
|
||||
it(`should restrict passwords that don't have the minimal length`);
|
||||
it(`should require passwords to contain a number if option is switched on`);
|
||||
it(`should not require passwords to contain a number if option is switched off`);
|
||||
it(`should require passwords to contain a symbol if option is switched on`);
|
||||
it(`should not require passwords to contain a symbol if option is switched off`);
|
||||
it(`should require passwords to contain a lowercase letter if option is switched on`);
|
||||
it(`should not require passwords to contain a lowercase letter if option is switched off`);
|
||||
it(`should require passwords to contain an uppercase letter if option is switched on`);
|
||||
it(`should not require passwords to contain an uppercase letter if option is switched off`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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/`,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -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"
|
||||
]*/
|
||||
},
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -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}`,
|
||||
);
|
||||
}
|
||||
|
@ -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', '/');
|
||||
})
|
||||
})
|
||||
*/
|
||||
*/
|
||||
|
@ -14,7 +14,7 @@
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
import './commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
// require('./commands')
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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),
|
||||
|
@ -22,7 +22,7 @@ services:
|
||||
image: 'cockroachdb/cockroach:v22.1.0'
|
||||
command: 'start-single-node --insecure --http-addr :9090'
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9090/health?ready=1"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:9090/health?ready=1']
|
||||
interval: '10s'
|
||||
timeout: '30s'
|
||||
retries: 5
|
||||
@ -36,10 +36,11 @@ services:
|
||||
prepare:
|
||||
image: node:18-alpine3.15
|
||||
working_dir: /e2e
|
||||
user: "$UID"
|
||||
user: '$UID'
|
||||
volumes:
|
||||
- .:/e2e
|
||||
command: "npm ci --omit=dev && npx run wait-on http://localhost:8080"
|
||||
- .:/e2e
|
||||
command: 'sh -c "npm ci --omit=dev && npm run lint && npx wait-on http://localhost:8080/debug/ready"'
|
||||
network_mode: host
|
||||
|
||||
e2e:
|
||||
image: cypress/included:10.3.0
|
||||
@ -51,9 +52,9 @@ services:
|
||||
prepare:
|
||||
condition: 'service_completed_successfully'
|
||||
working_dir: /e2e
|
||||
user: "$UID"
|
||||
user: '$UID'
|
||||
volumes:
|
||||
- .:/e2e
|
||||
- .:/e2e
|
||||
network_mode: host
|
||||
|
||||
networks:
|
||||
|
34
e2e/package-lock.json
generated
34
e2e/package-lock.json
generated
@ -11,7 +11,8 @@
|
||||
"debug": "^4.3.4",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mochawesome": "^7.1.3",
|
||||
"typescript": "^4.7.4",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.8.3",
|
||||
"wait-on": "^6.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -2125,6 +2126,20 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-bytes": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
||||
@ -2544,9 +2559,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
||||
"version": "4.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz",
|
||||
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@ -4327,6 +4342,11 @@
|
||||
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
|
||||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g=="
|
||||
},
|
||||
"pretty-bytes": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
||||
@ -4643,9 +4663,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ=="
|
||||
"version": "4.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz",
|
||||
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig=="
|
||||
},
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
|
@ -5,15 +5,18 @@
|
||||
"open": "npx cypress open",
|
||||
"e2e": "npx cypress run",
|
||||
"open:dev": "CYPRESS_BASE_URL=http://localhost:4200 CYPRESS_BACKEND_URL=http://localhost:8080 npm run open",
|
||||
"e2e:dev": "CYPRESS_BASE_URL=http://localhost:4200 CYPRESS_BACKEND_URL=http://localhost:8080 npm run e2e"
|
||||
"e2e:dev": "CYPRESS_BASE_URL=http://localhost:4200 CYPRESS_BACKEND_URL=http://localhost:8080 npm run e2e",
|
||||
"lint": "prettier --check cypress",
|
||||
"lint:fix": "prettier --write cypress"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mochawesome": "^7.1.3",
|
||||
"typescript": "^4.7.4",
|
||||
"wait-on": "^6.0.1"
|
||||
"wait-on": "^6.0.1",
|
||||
"typescript": "^4.8.3",
|
||||
"prettier": "^2.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.13",
|
||||
|
Loading…
Reference in New Issue
Block a user