mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-09 18:53:55 +00:00
cy10 changes
This commit is contained in:
parent
8434eaa9c0
commit
3a13f9da2a
23
console/cypress.config.ts
Normal file
23
console/cypress.config.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
reporter: 'mochawesome',
|
||||
|
||||
reporterOptions: {
|
||||
reportDir: 'cypress/results',
|
||||
overwrite: false,
|
||||
html: true,
|
||||
json: true,
|
||||
},
|
||||
|
||||
chromeWebSecurity: false,
|
||||
// experimentalSessionSupport: true,
|
||||
trashAssetsBeforeRuns: false,
|
||||
defaultCommandTimeout: 10000,
|
||||
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},
|
||||
},
|
||||
});
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"supportFile": "./cypress/support/index.ts",
|
||||
"reporter": "mochawesome",
|
||||
"reporterOptions": {
|
||||
"reportDir": "cypress/results",
|
||||
"overwrite": false,
|
||||
"html": true,
|
||||
"json": true
|
||||
},
|
||||
"chromeWebSecurity": false,
|
||||
"experimentalSessionSupport": true,
|
||||
"trashAssetsBeforeRuns": false
|
||||
}
|
||||
|
79
console/cypress/e2e/settings/private-labeling.cy.ts
Normal file
79
console/cypress/e2e/settings/private-labeling.cy.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import { apiAuth, apiCallProperties } from '../../support/api/apiauth';
|
||||
import { Policy, resetPolicy } from '../../support/api/policies';
|
||||
import { login, User } from '../../support/login/users';
|
||||
|
||||
describe('private labeling', () => {
|
||||
const orgPath = `${Cypress.env('consoleUrl')}/org`;
|
||||
|
||||
[User.OrgOwner].forEach((user) => {
|
||||
describe(`as user "${user}"`, () => {
|
||||
let api: apiCallProperties;
|
||||
|
||||
beforeEach(() => {
|
||||
login(user);
|
||||
cy.visit(orgPath);
|
||||
// TODO: Why force?
|
||||
cy.contains('[data-e2e=policy-card]', 'Private Labeling').contains('button', 'Modify').click({ force: true }); // TODO: select data-e2e
|
||||
});
|
||||
|
||||
customize('white', user);
|
||||
customize('dark', user);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function customize(theme: string, user: User) {
|
||||
describe(`${theme} theme`, () => {
|
||||
beforeEach(() => {
|
||||
apiAuth().then((api) => {
|
||||
resetPolicy(api, Policy.Label);
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('logo', () => {
|
||||
beforeEach('expand logo category', () => {
|
||||
cy.contains('[data-e2e=policy-category]', 'Logo').click(); // TODO: select data-e2e
|
||||
cy.fixture('logo.png').as('logo');
|
||||
});
|
||||
|
||||
it('should update a logo', () => {
|
||||
cy.get('[data-e2e=image-part-logo]')
|
||||
.find('input')
|
||||
.then(function (el) {
|
||||
const blob = Cypress.Blob.base64StringToBlob(this.logo, 'image/png');
|
||||
const file = new File([blob], 'images/logo.png', { type: 'image/png' });
|
||||
const list = new DataTransfer();
|
||||
|
||||
list.items.add(file);
|
||||
const myFileList = list.files;
|
||||
|
||||
el[0].files = myFileList;
|
||||
el[0].dispatchEvent(new Event('change', { bubbles: true }));
|
||||
});
|
||||
});
|
||||
it('should delete a logo');
|
||||
});
|
||||
it('should update an icon');
|
||||
it('should delete an icon');
|
||||
it.skip('should update the background color', () => {
|
||||
cy.contains('[data-e2e=color]', 'Background Color').find('button').click(); // TODO: select data-e2e
|
||||
cy.get('color-editable-input').find('input').clear().type('#ae44dc');
|
||||
cy.get('[data-e2e=save-colors-button]').click();
|
||||
cy.get('[data-e2e=header-user-avatar]').click();
|
||||
cy.contains('Logout All Users').click(); // TODO: select data-e2e
|
||||
login(User.LoginPolicyUser, undefined, true, null, () => {
|
||||
cy.pause();
|
||||
});
|
||||
});
|
||||
it('should update the primary color');
|
||||
it('should update the warning color');
|
||||
it('should update the font color');
|
||||
it('should update the font style');
|
||||
it('should hide the loginname suffix');
|
||||
it('should show the loginname suffix');
|
||||
it('should hide the watermark');
|
||||
it('should show the watermark');
|
||||
it('should show the current configuration');
|
||||
it('should reset the policy');
|
||||
});
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
import { apiAuth, apiCallProperties } from "../../support/api/apiauth";
|
||||
import { Policy, resetPolicy } from "../../support/api/policies";
|
||||
import { login, User } from "../../support/login/users";
|
||||
|
||||
describe("private labeling", ()=> {
|
||||
|
||||
const orgPath = `${Cypress.env('consoleUrl')}/org`
|
||||
|
||||
;[User.OrgOwner].forEach(user => {
|
||||
|
||||
describe(`as user "${user}"`, () => {
|
||||
|
||||
let api: apiCallProperties
|
||||
|
||||
|
||||
beforeEach(()=> {
|
||||
login(user)
|
||||
cy.visit(orgPath)
|
||||
// TODO: Why force?
|
||||
cy.contains('[data-e2e=policy-card]', 'Private Labeling').contains('button', 'Modify').click({force: true}) // TODO: select data-e2e
|
||||
})
|
||||
|
||||
customize('white', user)
|
||||
customize('dark', user)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
function customize(theme: string, user: User) {
|
||||
|
||||
describe(`${theme} theme`, () => {
|
||||
|
||||
beforeEach(() => {
|
||||
apiAuth().then(api => {
|
||||
resetPolicy(api, Policy.Label)
|
||||
})
|
||||
})
|
||||
|
||||
describe.skip('logo', () => {
|
||||
|
||||
beforeEach('expand logo category', () => {
|
||||
cy.contains('[data-e2e=policy-category]', 'Logo').click() // TODO: select data-e2e
|
||||
cy.fixture('logo.png').as('logo')
|
||||
})
|
||||
|
||||
it('should update a logo', () => {
|
||||
cy.get('[data-e2e=image-part-logo]').find('input').then(function (el) {
|
||||
const blob = Cypress.Blob.base64StringToBlob(this.logo, 'image/png')
|
||||
const file = new File([blob], 'images/logo.png', { type: 'image/png' })
|
||||
const list = new DataTransfer()
|
||||
|
||||
list.items.add(file)
|
||||
const myFileList = list.files
|
||||
|
||||
el[0].files = myFileList
|
||||
el[0].dispatchEvent(new Event('change', { bubbles: true }))
|
||||
})
|
||||
})
|
||||
it('should delete a logo')
|
||||
})
|
||||
it('should update an icon')
|
||||
it('should delete an icon')
|
||||
it.skip('should update the background color', () => {
|
||||
cy.contains('[data-e2e=color]', 'Background Color').find('button').click() // TODO: select data-e2e
|
||||
cy.get('color-editable-input').find('input').clear().type('#ae44dc')
|
||||
cy.get('[data-e2e=save-colors-button]').click()
|
||||
cy.get('[data-e2e=header-user-avatar]').click()
|
||||
cy.contains('Logout All Users').click() // TODO: select data-e2e
|
||||
login(User.LoginPolicyUser, true, null, () => {
|
||||
cy.pause()
|
||||
})
|
||||
})
|
||||
it('should update the primary color')
|
||||
it('should update the warning color')
|
||||
it('should update the font color')
|
||||
it('should update the font style')
|
||||
it('should hide the loginname suffix')
|
||||
it('should show the loginname suffix')
|
||||
it('should hide the watermark')
|
||||
it('should show the watermark')
|
||||
it('should show the current configuration')
|
||||
it('should reset the policy')
|
||||
})
|
||||
}
|
20
console/cypress/support/e2e.ts
Normal file
20
console/cypress/support/e2e.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/e2e.ts is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
@ -1,164 +1,187 @@
|
||||
export enum User {
|
||||
OrgOwner = 'org_owner',
|
||||
OrgOwnerViewer = 'org_owner_viewer',
|
||||
OrgProjectCreator = 'org_project_creator',
|
||||
LoginPolicyUser = 'login_policy_user',
|
||||
PasswordComplexityUser = 'password_complexity_user',
|
||||
IAMAdminUser = "zitadel-admin"
|
||||
OrgOwner = 'org_owner',
|
||||
OrgOwnerViewer = 'org_owner_viewer',
|
||||
OrgProjectCreator = 'org_project_creator',
|
||||
LoginPolicyUser = 'login_policy_user',
|
||||
PasswordComplexityUser = 'password_complexity_user',
|
||||
IAMAdminUser = 'zitadel-admin',
|
||||
}
|
||||
|
||||
export function login(user:User, force?: boolean, pw?: string, onUsernameScreen?: () => void, onPasswordScreen?: () => void, onAuthenticated?: () => void): void {
|
||||
let creds = credentials(user, pw)
|
||||
export function login(
|
||||
user: User,
|
||||
pw?: string,
|
||||
force?: boolean,
|
||||
onUsernameScreen?: () => void,
|
||||
onPasswordScreen?: () => void,
|
||||
onAuthenticated?: () => void,
|
||||
): void {
|
||||
let creds = credentials(user, pw);
|
||||
|
||||
const accountsUrl: string = Cypress.env('accountsUrl')
|
||||
const consoleUrl: string = Cypress.env('consoleUrl')
|
||||
const otherZitadelIdpInstance: boolean = Cypress.env('otherZitadelIdpInstance')
|
||||
const accountsUrl: string = Cypress.env('accountsUrl');
|
||||
const consoleUrl: string = Cypress.env('consoleUrl');
|
||||
const otherZitadelIdpInstance: boolean = Cypress.env('otherZitadelIdpInstance');
|
||||
|
||||
cy.session(creds.username, () => {
|
||||
cy.session(
|
||||
creds.username,
|
||||
() => {
|
||||
const cookies = new Map<string, string>();
|
||||
|
||||
const cookies = new Map<string, string>()
|
||||
if (otherZitadelIdpInstance) {
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/login*`,
|
||||
times: 1,
|
||||
},
|
||||
(req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies);
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies);
|
||||
});
|
||||
},
|
||||
).as('login');
|
||||
|
||||
if (otherZitadelIdpInstance) {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/login*`,
|
||||
times: 1
|
||||
}, (req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies)
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies)
|
||||
})
|
||||
}).as('login')
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'POST',
|
||||
url: `${accountsUrl}/loginname*`,
|
||||
times: 1,
|
||||
},
|
||||
(req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies);
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies);
|
||||
});
|
||||
},
|
||||
).as('loginName');
|
||||
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
url: `${accountsUrl}/loginname*`,
|
||||
times: 1
|
||||
}, (req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies)
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies)
|
||||
})
|
||||
}).as('loginName')
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'POST',
|
||||
url: `${accountsUrl}/password*`,
|
||||
times: 1,
|
||||
},
|
||||
(req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies);
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies);
|
||||
});
|
||||
},
|
||||
).as('password');
|
||||
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
url: `${accountsUrl}/password*`,
|
||||
times: 1
|
||||
}, (req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies)
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies)
|
||||
})
|
||||
}).as('password')
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/success*`,
|
||||
times: 1,
|
||||
},
|
||||
(req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies);
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies);
|
||||
});
|
||||
},
|
||||
).as('success');
|
||||
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/success*`,
|
||||
times: 1
|
||||
}, (req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies)
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies)
|
||||
})
|
||||
}).as('success')
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/oauth/v2/authorize/callback*`,
|
||||
times: 1,
|
||||
},
|
||||
(req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies);
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies);
|
||||
});
|
||||
},
|
||||
).as('callback');
|
||||
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/oauth/v2/authorize/callback*`,
|
||||
times: 1
|
||||
}, (req) => {
|
||||
req.headers['cookie'] = requestCookies(cookies)
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies)
|
||||
})
|
||||
}).as('callback')
|
||||
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/oauth/v2/authorize*`,
|
||||
times: 1,
|
||||
}, (req) => {
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies)
|
||||
})
|
||||
})
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: `${accountsUrl}/oauth/v2/authorize*`,
|
||||
times: 1,
|
||||
},
|
||||
(req) => {
|
||||
req.continue((res) => {
|
||||
updateCookies(res.headers['set-cookie'] as string[], cookies);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
cy.visit(`${consoleUrl}/loginname`, { retryOnNetworkFailure: true });
|
||||
|
||||
otherZitadelIdpInstance && cy.wait('@login');
|
||||
onUsernameScreen ? onUsernameScreen() : null;
|
||||
cy.get('#loginName').type(creds.username);
|
||||
cy.get('#submit-button').click();
|
||||
|
||||
otherZitadelIdpInstance && cy.wait('@loginName');
|
||||
onPasswordScreen ? onPasswordScreen() : null;
|
||||
cy.get('#password').type(creds.password);
|
||||
cy.get('#submit-button').click();
|
||||
|
||||
onAuthenticated ? onAuthenticated() : null;
|
||||
|
||||
otherZitadelIdpInstance && cy.wait('@callback');
|
||||
|
||||
cy.location('pathname', { timeout: 5 * 1000 }).should('eq', '/');
|
||||
},
|
||||
{
|
||||
validate: () => {
|
||||
if (force) {
|
||||
throw new Error('clear session');
|
||||
}
|
||||
|
||||
cy.visit(`${consoleUrl}/loginname`, { retryOnNetworkFailure: true });
|
||||
|
||||
otherZitadelIdpInstance && cy.wait('@login')
|
||||
onUsernameScreen ? onUsernameScreen() : null
|
||||
cy.get('#loginName').type(creds.username)
|
||||
cy.get('#submit-button').click()
|
||||
|
||||
otherZitadelIdpInstance && cy.wait('@loginName')
|
||||
onPasswordScreen ? onPasswordScreen() : null
|
||||
cy.get('#password').type(creds.password)
|
||||
cy.get('#submit-button').click()
|
||||
|
||||
onAuthenticated ? onAuthenticated() : null
|
||||
|
||||
otherZitadelIdpInstance && cy.wait('@callback')
|
||||
|
||||
cy.location('pathname', {timeout: 5 * 1000}).should('eq', '/');
|
||||
|
||||
}, {
|
||||
validate: () => {
|
||||
|
||||
if (force) {
|
||||
throw new Error("clear session");
|
||||
}
|
||||
|
||||
cy.visit(`${consoleUrl}/users/me`)
|
||||
}
|
||||
})
|
||||
cy.visit(`${consoleUrl}/users/me`);
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function username(withoutDomain: string, project?: string): string {
|
||||
return `${withoutDomain}@${project ? `${project}.` : ''}${host(Cypress.env('apiUrl')).replace('api.', '')}`
|
||||
return `${withoutDomain}@${project ? `${project}.` : ''}${host(Cypress.env('apiUrl')).replace('api.', '')}`;
|
||||
}
|
||||
|
||||
function credentials(user: User, pw?: string) {
|
||||
const isAdmin = user == User.IAMAdminUser
|
||||
return {
|
||||
username: username(isAdmin ? user : `${user}_user_name`, isAdmin ? 'caos-ag' : Cypress.env('org')),
|
||||
password: pw ? pw : Cypress.env(`${user}_password`)
|
||||
}
|
||||
const isAdmin = user == User.IAMAdminUser;
|
||||
return {
|
||||
username: username(isAdmin ? user : `${user}_user_name`, isAdmin ? 'caos-ag' : Cypress.env('org')),
|
||||
password: pw ? pw : Cypress.env(`${user}_password`),
|
||||
};
|
||||
}
|
||||
|
||||
function updateCookies(newCookies: string[] | undefined, currentCookies: Map<string, string>) {
|
||||
if (newCookies === undefined) {
|
||||
return
|
||||
}
|
||||
newCookies.forEach(cs => {
|
||||
cs.split('; ').forEach(cookie => {
|
||||
const idx = cookie.indexOf('=')
|
||||
currentCookies.set(cookie.substring(0,idx), cookie.substring(idx+1))
|
||||
})
|
||||
})
|
||||
if (newCookies === undefined) {
|
||||
return;
|
||||
}
|
||||
newCookies.forEach((cs) => {
|
||||
cs.split('; ').forEach((cookie) => {
|
||||
const idx = cookie.indexOf('=');
|
||||
currentCookies.set(cookie.substring(0, idx), cookie.substring(idx + 1));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function requestCookies(currentCookies: Map<string, string>): string[] {
|
||||
let list: Array<string> = []
|
||||
currentCookies.forEach((val, key) => {
|
||||
list.push(key+"="+val)
|
||||
})
|
||||
return list
|
||||
let list: Array<string> = [];
|
||||
currentCookies.forEach((val, key) => {
|
||||
list.push(key + '=' + val);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
export function host(url: string): string {
|
||||
return stripPort(stripProtocol(url))
|
||||
return stripPort(stripProtocol(url));
|
||||
}
|
||||
|
||||
function stripPort(s: string): string {
|
||||
const idx = s.indexOf(":")
|
||||
return idx === -1 ? s : s.substring(0,idx)
|
||||
const idx = s.indexOf(':');
|
||||
return idx === -1 ? s : s.substring(0, idx);
|
||||
}
|
||||
|
||||
function stripProtocol(url: string): string {
|
||||
return url.replace('http://', '').replace('https://', '')
|
||||
return url.replace('http://', '').replace('https://', '');
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["es5", "dom"],
|
||||
"types": ["cypress"]
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"target": "es5",
|
||||
"lib": ["es5", "dom"],
|
||||
"types": ["cypress"]
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ E2E_ORG_PROJECT_CREATOR_PW=Password1!
|
||||
E2E_PASSWORD_COMPLEXITY_USER_PW=Password1!
|
||||
E2E_LOGIN_POLICY_USER_PW=Password1!
|
||||
E2E_SERVICEACCOUNT_KEY_PATH="${projectRoot}/.keys/e2e.json"
|
||||
E2E_CONSOLE_URL="http://localhost:4200"
|
||||
E2E_CONSOLE_URL="http://localhost:4200/ui/console"
|
||||
E2E_API_URL="http://localhost:50002"
|
||||
E2E_ACCOUNTS_URL="http://localhost:50003"
|
||||
E2E_ISSUER_URL="http://localhost:50002/oauth/v2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user