mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-12-27 23:40:28 +05:30
Improve tests structure
This commit is contained in:
parent
5d411fd6ca
commit
ba49382fb6
@ -1,216 +1,221 @@
|
||||
import { account1 } from '../../fixtures/accounts.json';
|
||||
|
||||
it('should request password reset', () => {
|
||||
const captchaCode = 'captchaCode';
|
||||
const emailMask = 'fo*@gm*l.**m';
|
||||
describe('Forgot / reset password', () => {
|
||||
it('should request password reset', () => {
|
||||
const captchaCode = 'captchaCode';
|
||||
const emailMask = 'fo*@gm*l.**m';
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/forgot-password',
|
||||
response: {
|
||||
success: true,
|
||||
data: {
|
||||
emailMask,
|
||||
},
|
||||
},
|
||||
}).as('forgot');
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.username}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Forgot password')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/forgot-password');
|
||||
|
||||
cy.getByTestId('forgot-password-login').should('contain', account1.username);
|
||||
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
login: account1.username,
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
|
||||
cy.getByTestId('auth-body').should('contain', emailMask);
|
||||
});
|
||||
|
||||
it('should allow change login', () => {
|
||||
const captchaCode = 'captchaCode';
|
||||
const login = 'foo';
|
||||
const emailMask = 'fo*@gm*l.**m';
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/forgot-password',
|
||||
response: {
|
||||
success: true,
|
||||
data: {
|
||||
emailMask,
|
||||
},
|
||||
},
|
||||
}).as('forgot');
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.username}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Forgot password')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/forgot-password');
|
||||
|
||||
cy.getByTestId('edit-login').click();
|
||||
cy.get('[name=login]').should('have.value', account1.username);
|
||||
|
||||
cy.get('[name=login]').type(`{selectall}${login}`);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
login,
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
});
|
||||
|
||||
it('should allow enter login', () => {
|
||||
const captchaCode = 'captchaCode';
|
||||
const login = 'foo';
|
||||
const emailMask = 'fo*@gm*l.**m';
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/forgot-password',
|
||||
response: {
|
||||
success: true,
|
||||
data: {
|
||||
emailMask,
|
||||
},
|
||||
},
|
||||
}).as('forgot');
|
||||
|
||||
cy.visit('/forgot-password');
|
||||
|
||||
cy.get('[name=login]').type(login);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
login,
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
});
|
||||
|
||||
it('should recover password', () => {
|
||||
const key = 'key';
|
||||
const newPassword = 'newPassword';
|
||||
|
||||
cy.server();
|
||||
cy.login({
|
||||
accounts: ['default'],
|
||||
updateState: false,
|
||||
rawApiResp: true,
|
||||
}).then(({ accounts: [account] }) => {
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/recover-password',
|
||||
response: account,
|
||||
}).as('recover');
|
||||
url: '/api/authentication/forgot-password',
|
||||
response: {
|
||||
success: true,
|
||||
data: {
|
||||
emailMask,
|
||||
},
|
||||
},
|
||||
}).as('forgot');
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.username}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Forgot password')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/forgot-password');
|
||||
|
||||
cy.getByTestId('forgot-password-login').should(
|
||||
'contain',
|
||||
account1.username,
|
||||
);
|
||||
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
login: account1.username,
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
|
||||
cy.getByTestId('auth-body').should('contain', emailMask);
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
it('should allow change login', () => {
|
||||
const captchaCode = 'captchaCode';
|
||||
const login = 'foo';
|
||||
const emailMask = 'fo*@gm*l.**m';
|
||||
|
||||
cy.get('[name=login]').type(`${account1.username}{enter}`);
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/forgot-password',
|
||||
response: {
|
||||
success: true,
|
||||
data: {
|
||||
emailMask,
|
||||
},
|
||||
},
|
||||
}).as('forgot');
|
||||
|
||||
cy.location('pathname').should('eq', '/password');
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Forgot password')
|
||||
.click();
|
||||
cy.get('[name=login]').type(`${account1.username}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/forgot-password');
|
||||
cy.location('pathname').should('eq', '/password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Already have')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Forgot password')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
cy.location('pathname').should('eq', '/forgot-password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Contact support')
|
||||
.click();
|
||||
cy.getByTestId('feedbackPopup').should('be.visible');
|
||||
cy.getByTestId('feedback-popup-close').click();
|
||||
cy.getByTestId('feedbackPopup').should('not.be.visible');
|
||||
cy.getByTestId('edit-login').click();
|
||||
cy.get('[name=login]').should('have.value', account1.username);
|
||||
|
||||
cy.get('[name=key]').type(key);
|
||||
cy.get('[name=newPassword]').type(newPassword);
|
||||
cy.get('[name=newRePassword]').type(newPassword);
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
cy.get('[name=login]').type(`{selectall}${login}`);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
cy.wait('@recover')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
key,
|
||||
newPassword,
|
||||
newRePassword: newPassword,
|
||||
}).toString(),
|
||||
);
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
login,
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
});
|
||||
|
||||
it('should allow enter login', () => {
|
||||
const captchaCode = 'captchaCode';
|
||||
const login = 'foo';
|
||||
const emailMask = 'fo*@gm*l.**m';
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/forgot-password',
|
||||
response: {
|
||||
success: true,
|
||||
data: {
|
||||
emailMask,
|
||||
},
|
||||
},
|
||||
}).as('forgot');
|
||||
|
||||
cy.visit('/forgot-password');
|
||||
|
||||
cy.get('[name=login]').type(login);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
login,
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
});
|
||||
|
||||
it('should recover password', () => {
|
||||
const key = 'key';
|
||||
const newPassword = 'newPassword';
|
||||
|
||||
cy.server();
|
||||
cy.login({
|
||||
accounts: ['default'],
|
||||
updateState: false,
|
||||
rawApiResp: true,
|
||||
}).then(({ accounts: [account] }) => {
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/recover-password',
|
||||
response: account,
|
||||
}).as('recover');
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.username}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Forgot password')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/forgot-password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Already have')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Contact support')
|
||||
.click();
|
||||
cy.getByTestId('feedbackPopup').should('be.visible');
|
||||
cy.getByTestId('feedback-popup-close').click();
|
||||
cy.getByTestId('feedbackPopup').should('not.be.visible');
|
||||
|
||||
cy.get('[name=key]').type(key);
|
||||
cy.get('[name=newPassword]').type(newPassword);
|
||||
cy.get('[name=newRePassword]').type(newPassword);
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
|
||||
cy.wait('@recover')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
key,
|
||||
newPassword,
|
||||
newRePassword: newPassword,
|
||||
}).toString(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
// account1 - authenticated
|
||||
// account2 - invalid refreshToken
|
||||
import { account1, account2 } from '../fixtures/accounts.json';
|
||||
import { account1, account2 } from '../../fixtures/accounts.json';
|
||||
|
||||
const multiAccount = createState();
|
||||
const multiAccountWithBadTokens = createState();
|
@ -8,243 +8,99 @@ const defaults = {
|
||||
scope: 'account_info,account_email',
|
||||
};
|
||||
|
||||
it('should complete oauth', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
describe('OAuth', () => {
|
||||
it('should complete oauth', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(`/oauth2/v1/ely?${new URLSearchParams(defaults)}`);
|
||||
cy.visit(`/oauth2/v1/ely?${new URLSearchParams(defaults)}`);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
it('should restore previous oauthData if any', () => {
|
||||
localStorage.setItem(
|
||||
'oauthData',
|
||||
JSON.stringify({
|
||||
timestamp: Date.now() - 3600,
|
||||
payload: {
|
||||
clientId: 'ely',
|
||||
redirectUrl: 'http://ely.by/authorization/oauth',
|
||||
responseType: 'code',
|
||||
description: null,
|
||||
scope: 'account_info account_email',
|
||||
loginHint: null,
|
||||
state: null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
cy.login({ accounts: ['default'] });
|
||||
it('should restore previous oauthData if any', () => {
|
||||
localStorage.setItem(
|
||||
'oauthData',
|
||||
JSON.stringify({
|
||||
timestamp: Date.now() - 3600,
|
||||
payload: {
|
||||
clientId: 'ely',
|
||||
redirectUrl: 'http://ely.by/authorization/oauth',
|
||||
responseType: 'code',
|
||||
description: null,
|
||||
scope: 'account_info account_email',
|
||||
loginHint: null,
|
||||
state: null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
cy.visit('/');
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
it('should ask to choose an account if user has multiple', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] }).then(
|
||||
({ accounts: [account] }) => {
|
||||
cy.visit(`/oauth2/v1/ely?${new URLSearchParams(defaults)}`);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
// TODO: remove api mocks, when we will be able to revoke permissions
|
||||
it('should prompt for permissions', () => {
|
||||
cy.server();
|
||||
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
// NOTE: can not use cypress glob syntax, because it will break due to
|
||||
// '%2F%2F' (//) in redirect_uri
|
||||
// url: '/api/oauth2/v1/complete/*',
|
||||
url: new RegExp('/api/oauth2/v1/complete'),
|
||||
response: {
|
||||
statusCode: 401,
|
||||
error: 'accept_required',
|
||||
},
|
||||
status: 401,
|
||||
}).as('complete');
|
||||
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.wait('@complete');
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.server({ enable: false });
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
|
||||
cy.url().should('match', /^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/);
|
||||
});
|
||||
|
||||
it('should allow sign in during oauth (guest oauth)', () => {
|
||||
cy.visit(`/oauth2/v1/ely?${new URLSearchParams(defaults)}`);
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
// TODO: enable, when backend api will return correct response on auth decline
|
||||
xit('should redirect to error page, when permission request declined', () => {
|
||||
cy.server();
|
||||
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
// NOTE: can not use cypress glob syntax, because it will break due to
|
||||
// '%2F%2F' (//) in redirect_uri
|
||||
// url: '/api/oauth2/v1/complete/*',
|
||||
url: new RegExp('/api/oauth2/v1/complete'),
|
||||
response: {
|
||||
statusCode: 401,
|
||||
error: 'accept_required',
|
||||
},
|
||||
status: 401,
|
||||
}).as('complete');
|
||||
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.wait('@complete');
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.server({ enable: false });
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Decline')
|
||||
.click();
|
||||
|
||||
cy.url().should('include', 'error=access_denied');
|
||||
});
|
||||
|
||||
describe('login_hint', () => {
|
||||
it('should automatically choose account, when id in login_hint is present', () => {
|
||||
it('should ask to choose an account if user has multiple', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] }).then(
|
||||
({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
// suggest preferred username
|
||||
// https://docs.ely.by/ru/oauth.html#id3
|
||||
login_hint: account.id,
|
||||
})}`,
|
||||
);
|
||||
cy.visit(`/oauth2/v1/ely?${new URLSearchParams(defaults)}`);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should automatically choose account, when email in login_hint is present', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] }).then(
|
||||
({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
// suggest preferred username
|
||||
// https://docs.ely.by/ru/oauth.html#id3
|
||||
login_hint: account.email,
|
||||
})}`,
|
||||
);
|
||||
// TODO: remove api mocks, when we will be able to revoke permissions
|
||||
it('should prompt for permissions', () => {
|
||||
cy.server();
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
// NOTE: can not use cypress glob syntax, because it will break due to
|
||||
// '%2F%2F' (//) in redirect_uri
|
||||
// url: '/api/oauth2/v1/complete/*',
|
||||
url: new RegExp('/api/oauth2/v1/complete'),
|
||||
response: {
|
||||
statusCode: 401,
|
||||
error: 'accept_required',
|
||||
},
|
||||
);
|
||||
});
|
||||
status: 401,
|
||||
}).as('complete');
|
||||
|
||||
it('should automatically choose account, when username in login_hint is present and it is not an active account', () => {
|
||||
cy.login({ accounts: ['default2', 'default'] }).then(
|
||||
({
|
||||
// try to authenticate with an account, that is not currently active one
|
||||
accounts: [, account],
|
||||
}) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
// suggest preferred username
|
||||
// https://docs.ely.by/ru/oauth.html#id3
|
||||
login_hint: account.username,
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('prompts', () => {
|
||||
it('should prompt for account', () => {
|
||||
cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
prompt: 'select_account',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow sign in with another account', () => {
|
||||
cy.login({ accounts: ['default2'] });
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
prompt: 'select_account',
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
cy.wait('@complete');
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.server({ enable: false });
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('another account')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
|
||||
cy.url().should('match', /^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/);
|
||||
});
|
||||
|
||||
it('should allow sign in during oauth (guest oauth)', () => {
|
||||
cy.visit(`/oauth2/v1/ely?${new URLSearchParams(defaults)}`);
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
@ -256,7 +112,23 @@ describe('prompts', () => {
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
it('should prompt for permissions', () => {
|
||||
// TODO: enable, when backend api will return correct response on auth decline
|
||||
xit('should redirect to error page, when permission request declined', () => {
|
||||
cy.server();
|
||||
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
// NOTE: can not use cypress glob syntax, because it will break due to
|
||||
// '%2F%2F' (//) in redirect_uri
|
||||
// url: '/api/oauth2/v1/complete/*',
|
||||
url: new RegExp('/api/oauth2/v1/complete'),
|
||||
response: {
|
||||
statusCode: 401,
|
||||
error: 'accept_required',
|
||||
},
|
||||
status: 401,
|
||||
}).as('complete');
|
||||
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
@ -264,33 +136,14 @@ describe('prompts', () => {
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
prompt: 'consent',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.wait('@complete');
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
|
||||
cy.url().should('match', /^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/);
|
||||
});
|
||||
|
||||
// TODO: enable, when backend api will return correct response on auth decline
|
||||
xit('should redirect to error page, when permission request declined', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
prompt: 'consent',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/permissions');
|
||||
cy.server({ enable: false });
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Decline')
|
||||
@ -299,8 +152,190 @@ describe('prompts', () => {
|
||||
cy.url().should('include', 'error=access_denied');
|
||||
});
|
||||
|
||||
it('should prompt for both account and permissions', () => {
|
||||
cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => {
|
||||
describe('login_hint', () => {
|
||||
it('should automatically choose account, when id in login_hint is present', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] }).then(
|
||||
({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
// suggest preferred username
|
||||
// https://docs.ely.by/ru/oauth.html#id3
|
||||
login_hint: account.id,
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should automatically choose account, when email in login_hint is present', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] }).then(
|
||||
({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
// suggest preferred username
|
||||
// https://docs.ely.by/ru/oauth.html#id3
|
||||
login_hint: account.email,
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should automatically choose account, when username in login_hint is present and it is not an active account', () => {
|
||||
cy.login({ accounts: ['default2', 'default'] }).then(
|
||||
({
|
||||
// try to authenticate with an account, that is not currently active one
|
||||
accounts: [, account],
|
||||
}) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
// suggest preferred username
|
||||
// https://docs.ely.by/ru/oauth.html#id3
|
||||
login_hint: account.username,
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('prompts', () => {
|
||||
it('should prompt for account', () => {
|
||||
cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
prompt: 'select_account',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow sign in with another account', () => {
|
||||
cy.login({ accounts: ['default2'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
prompt: 'select_account',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('another account')
|
||||
.click();
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
it('should prompt for permissions', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
prompt: 'consent',
|
||||
})}`,
|
||||
);
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
|
||||
cy.url().should(
|
||||
'match',
|
||||
/^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/,
|
||||
);
|
||||
});
|
||||
|
||||
// TODO: enable, when backend api will return correct response on auth decline
|
||||
xit('should redirect to error page, when permission request declined', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
prompt: 'consent',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/permissions');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Decline')
|
||||
.click();
|
||||
|
||||
cy.url().should('include', 'error=access_denied');
|
||||
});
|
||||
|
||||
it('should prompt for both account and permissions', () => {
|
||||
cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
prompt: 'select_account,consent',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
|
||||
cy.url().should(
|
||||
'match',
|
||||
/^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow sign in during oauth (guest oauth)', () => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
@ -310,13 +345,13 @@ describe('prompts', () => {
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
assertPermissions();
|
||||
|
||||
@ -331,90 +366,63 @@ describe('prompts', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow sign in during oauth (guest oauth)', () => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
prompt: 'select_account,consent',
|
||||
})}`,
|
||||
);
|
||||
describe('static pages', () => {
|
||||
it('should authenticate using static page', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'static_page',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
cy.url().should('include', 'oauth/finish#{%22auth_code%22:');
|
||||
});
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
it('should authenticate using static page with code', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'static_page_with_code',
|
||||
})}`,
|
||||
);
|
||||
|
||||
assertPermissions();
|
||||
cy.url().should('include', 'oauth/finish#{%22auth_code%22:');
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
cy.getByTestId('oauth-code-container').should(
|
||||
'contain',
|
||||
'provide the following code',
|
||||
);
|
||||
|
||||
cy.url().should('match', /^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('static pages', () => {
|
||||
it('should authenticate using static page', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'static_page',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', 'oauth/finish#{%22auth_code%22:');
|
||||
// just click on copy, but we won't assert if the string was copied
|
||||
// because it is a little bit complicated
|
||||
// https://github.com/cypress-io/cypress/issues/2752
|
||||
cy.getByTestId('oauth-code-container')
|
||||
.contains('Copy')
|
||||
.click({
|
||||
// TODO: forcing, because currently we have needless re-renders, that causing
|
||||
// button to disappear for some time and to be unclickable
|
||||
force: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should authenticate using static page with code', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
function assertPermissions() {
|
||||
cy.url().should('include', '/oauth/permissions');
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'static_page_with_code',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', 'oauth/finish#{%22auth_code%22:');
|
||||
|
||||
cy.getByTestId('oauth-code-container').should(
|
||||
cy.getByTestId('auth-header').should('contain', 'Application permissions');
|
||||
cy.getByTestId('auth-body').should(
|
||||
'contain',
|
||||
'provide the following code',
|
||||
'Access to your profile data (except E‑mail)',
|
||||
);
|
||||
|
||||
// just click on copy, but we won't assert if the string was copied
|
||||
// because it is a little bit complicated
|
||||
// https://github.com/cypress-io/cypress/issues/2752
|
||||
cy.getByTestId('oauth-code-container')
|
||||
.contains('Copy')
|
||||
.click({
|
||||
// TODO: forcing, because currently we have needless re-renders, that causing
|
||||
// button to disappear for some time and to be unclickable
|
||||
force: true,
|
||||
});
|
||||
});
|
||||
cy.getByTestId('auth-body').should(
|
||||
'contain',
|
||||
'Access to your E‑mail address',
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function assertPermissions() {
|
||||
cy.url().should('include', '/oauth/permissions');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Application permissions');
|
||||
cy.getByTestId('auth-body').should(
|
||||
'contain',
|
||||
'Access to your profile data (except E‑mail)',
|
||||
);
|
||||
cy.getByTestId('auth-body').should(
|
||||
'contain',
|
||||
'Access to your E‑mail address',
|
||||
);
|
||||
}
|
||||
|
@ -1,145 +1,147 @@
|
||||
it('should register', () => {
|
||||
const username = `test${Date.now()}`;
|
||||
const email = `${Date.now()}@gmail.com`;
|
||||
const password = String(Date.now());
|
||||
const captchaCode = 'captchaCode';
|
||||
const activationKey = 'activationKey';
|
||||
describe('Register', () => {
|
||||
it('should register', () => {
|
||||
const username = `test${Date.now()}`;
|
||||
const email = `${Date.now()}@gmail.com`;
|
||||
const password = String(Date.now());
|
||||
const captchaCode = 'captchaCode';
|
||||
const activationKey = 'activationKey';
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/signup',
|
||||
response: {
|
||||
success: true,
|
||||
},
|
||||
}).as('signup');
|
||||
cy.login({
|
||||
accounts: ['default'],
|
||||
updateState: false,
|
||||
rawApiResp: true,
|
||||
}).then(({ accounts: [account] }) => {
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/signup/confirm',
|
||||
response: account,
|
||||
}).as('activate');
|
||||
url: '/api/signup',
|
||||
response: {
|
||||
success: true,
|
||||
},
|
||||
}).as('signup');
|
||||
cy.login({
|
||||
accounts: ['default'],
|
||||
updateState: false,
|
||||
rawApiResp: true,
|
||||
}).then(({ accounts: [account] }) => {
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/signup/confirm',
|
||||
response: account,
|
||||
}).as('activate');
|
||||
});
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains('Join')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/register');
|
||||
|
||||
cy.get('[name=username]').type(username);
|
||||
cy.get('[name=email]').type(email);
|
||||
cy.get('[name=password]').type(password);
|
||||
cy.get('[name=rePassword]').type(password);
|
||||
cy.get('[name=rulesAgreement]').should('not.be.checked');
|
||||
cy.get('[name=rulesAgreement]')
|
||||
.parent()
|
||||
.click();
|
||||
cy.get('[name=rulesAgreement]').should('be.checked');
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.wait('@signup')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
email,
|
||||
username,
|
||||
password,
|
||||
rePassword: password,
|
||||
rulesAgreement: '1',
|
||||
lang: 'en',
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/activation');
|
||||
|
||||
cy.get('[name=key]').type(`${activationKey}{enter}`);
|
||||
|
||||
cy.wait('@activate')
|
||||
.its('requestBody')
|
||||
.should('eq', `key=${activationKey}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains('Join')
|
||||
.click();
|
||||
it('should allow activation', () => {
|
||||
const activationKey = 'activationKey';
|
||||
|
||||
cy.location('pathname').should('eq', '/register');
|
||||
cy.server();
|
||||
cy.login({
|
||||
accounts: ['default'],
|
||||
updateState: false,
|
||||
rawApiResp: true,
|
||||
}).then(({ accounts: [account] }) => {
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/signup/confirm',
|
||||
response: account,
|
||||
}).as('activate');
|
||||
});
|
||||
cy.visit('/register');
|
||||
|
||||
cy.get('[name=username]').type(username);
|
||||
cy.get('[name=email]').type(email);
|
||||
cy.get('[name=password]').type(password);
|
||||
cy.get('[name=rePassword]').type(password);
|
||||
cy.get('[name=rulesAgreement]').should('not.be.checked');
|
||||
cy.get('[name=rulesAgreement]')
|
||||
.parent()
|
||||
.click();
|
||||
cy.get('[name=rulesAgreement]').should('be.checked');
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Already have')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/activation');
|
||||
|
||||
cy.get('[name=key]').type(`${activationKey}{enter}`);
|
||||
|
||||
cy.wait('@activate')
|
||||
.its('requestBody')
|
||||
.should('eq', `key=${activationKey}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.wait('@signup')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
email,
|
||||
username,
|
||||
password,
|
||||
rePassword: password,
|
||||
rulesAgreement: '1',
|
||||
lang: 'en',
|
||||
captcha: captchaCode,
|
||||
}).toString(),
|
||||
);
|
||||
it('should allow resend code', () => {
|
||||
const email = `${Date.now()}@gmail.com`;
|
||||
const captchaCode = 'captchaCode';
|
||||
|
||||
cy.location('pathname').should('eq', '/activation');
|
||||
|
||||
cy.get('[name=key]').type(`${activationKey}{enter}`);
|
||||
|
||||
cy.wait('@activate')
|
||||
.its('requestBody')
|
||||
.should('eq', `key=${activationKey}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
|
||||
it('should allow activation', () => {
|
||||
const activationKey = 'activationKey';
|
||||
|
||||
cy.server();
|
||||
cy.login({
|
||||
accounts: ['default'],
|
||||
updateState: false,
|
||||
rawApiResp: true,
|
||||
}).then(({ accounts: [account] }) => {
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/signup/confirm',
|
||||
response: account,
|
||||
}).as('activate');
|
||||
url: '/api/signup/repeat-message',
|
||||
response: { success: true },
|
||||
}).as('resend');
|
||||
cy.visit('/register');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('not received')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/resend-activation');
|
||||
|
||||
cy.get('[name=email]').type(email);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.wait('@resend')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({ email, captcha: captchaCode }).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/activation');
|
||||
});
|
||||
cy.visit('/register');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Already have')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/activation');
|
||||
|
||||
cy.get('[name=key]').type(`${activationKey}{enter}`);
|
||||
|
||||
cy.wait('@activate')
|
||||
.its('requestBody')
|
||||
.should('eq', `key=${activationKey}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
|
||||
it('should allow resend code', () => {
|
||||
const email = `${Date.now()}@gmail.com`;
|
||||
const captchaCode = 'captchaCode';
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/signup/repeat-message',
|
||||
response: { success: true },
|
||||
}).as('resend');
|
||||
cy.visit('/register');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('not received')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/resend-activation');
|
||||
|
||||
cy.get('[name=email]').type(email);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.wait('@resend')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({ email, captcha: captchaCode }).toString(),
|
||||
);
|
||||
|
||||
cy.location('pathname').should('eq', '/activation');
|
||||
});
|
||||
|
@ -1,206 +1,133 @@
|
||||
import { account1, account2 } from '../../fixtures/accounts.json';
|
||||
|
||||
it('should sign in', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(account1.password);
|
||||
cy.get('[name=rememberMe]').should('be.checked');
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.should(() => {
|
||||
const state = JSON.parse(localStorage.getItem('redux-storage') || '');
|
||||
expect(state.accounts.available).to.have.length(1);
|
||||
|
||||
const [account] = state.accounts.available;
|
||||
expect(account.username).to.be.equal(account1.username);
|
||||
expect(account.id)
|
||||
.to.be.a('number')
|
||||
.and.to.be.gt(0);
|
||||
expect(account.email)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.token)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.refreshToken)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
|
||||
expect(state.accounts.active).to.be.equal(account.id);
|
||||
|
||||
const { user } = state;
|
||||
expect(user.id).to.be.equal(account.id);
|
||||
expect(user.username).to.be.equal(account.username);
|
||||
expect(user.isGuest).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('should sign in without remember me', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(account1.password);
|
||||
cy.get('[name=rememberMe]')
|
||||
.parent()
|
||||
.click();
|
||||
cy.get('[name=rememberMe]').should('not.be.checked');
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.should(() => {
|
||||
const state = JSON.parse(localStorage.getItem('redux-storage') || '');
|
||||
expect(state.accounts.available).to.have.length(1);
|
||||
|
||||
const [account] = state.accounts.available;
|
||||
expect(account.username).to.be.equal(account1.username);
|
||||
expect(account.id)
|
||||
.to.be.a('number')
|
||||
.and.to.be.gt(0);
|
||||
expect(account.email)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.token)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.refreshToken).eql(null);
|
||||
|
||||
expect(state.accounts.active).to.be.equal(account.id);
|
||||
|
||||
const { user } = state;
|
||||
expect(user.id).to.be.equal(account.id);
|
||||
expect(user.username).to.be.equal(account.username);
|
||||
expect(user.isGuest).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('should sign in with totp', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/login',
|
||||
response: {
|
||||
success: false,
|
||||
errors: { totp: 'error.totp_required' },
|
||||
},
|
||||
});
|
||||
|
||||
cy.get('[name=password]').type(account1.password);
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.url().should('include', '/mfa');
|
||||
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/login',
|
||||
}).as('login');
|
||||
|
||||
cy.get('[name=totp]').type('123{enter}');
|
||||
|
||||
cy.wait('@login')
|
||||
.its('requestBody')
|
||||
.should('include', 'totp=123');
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
|
||||
it('should allow logout', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
cy.getByTestId('toolbar').should('contain', 'Join');
|
||||
});
|
||||
|
||||
describe('multi account', () => {
|
||||
it('should allow sign in with another account', () => {
|
||||
cy.login({ accounts: ['default2'] });
|
||||
|
||||
describe('Sign in / Log out', () => {
|
||||
it('should sign in', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
|
||||
cy.get('[data-e2e-go-back]').should('exist');
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
cy.get('[name=password]').type(account1.password);
|
||||
cy.get('[name=rememberMe]').should('be.checked');
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
.should(() => {
|
||||
const state = JSON.parse(localStorage.getItem('redux-storage') || '');
|
||||
expect(state.accounts.available).to.have.length(1);
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 1);
|
||||
const [account] = state.accounts.available;
|
||||
expect(account.username).to.be.equal(account1.username);
|
||||
expect(account.id)
|
||||
.to.be.a('number')
|
||||
.and.to.be.gt(0);
|
||||
expect(account.email)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.token)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.refreshToken)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
|
||||
cy.get('[data-e2e-account-id]')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
expect(state.accounts.active).to.be.equal(account.id);
|
||||
|
||||
const { user } = state;
|
||||
expect(user.id).to.be.equal(account.id);
|
||||
expect(user.username).to.be.equal(account.username);
|
||||
expect(user.isGuest).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('should go back to profile from login screen', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
it('should sign in without remember me', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(account1.password);
|
||||
cy.get('[name=rememberMe]')
|
||||
.parent()
|
||||
.click();
|
||||
cy.get('[name=rememberMe]').should('not.be.checked');
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
.should(() => {
|
||||
const state = JSON.parse(localStorage.getItem('redux-storage') || '');
|
||||
expect(state.accounts.available).to.have.length(1);
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
const [account] = state.accounts.available;
|
||||
expect(account.username).to.be.equal(account1.username);
|
||||
expect(account.id)
|
||||
.to.be.a('number')
|
||||
.and.to.be.gt(0);
|
||||
expect(account.email)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.token)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.refreshToken).eql(null);
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
expect(state.accounts.active).to.be.equal(account.id);
|
||||
|
||||
cy.get('[data-e2e-go-back]').click();
|
||||
const { user } = state;
|
||||
expect(user.id).to.be.equal(account.id);
|
||||
expect(user.username).to.be.equal(account.username);
|
||||
expect(user.isGuest).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it('should sign in with totp', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/login',
|
||||
response: {
|
||||
success: false,
|
||||
errors: { totp: 'error.totp_required' },
|
||||
},
|
||||
});
|
||||
|
||||
cy.get('[name=password]').type(account1.password);
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
cy.url().should('include', '/mfa');
|
||||
|
||||
cy.route({
|
||||
method: 'POST',
|
||||
url: '/api/authentication/login',
|
||||
}).as('login');
|
||||
|
||||
cy.get('[name=totp]').type('123{enter}');
|
||||
|
||||
cy.wait('@login')
|
||||
.its('requestBody')
|
||||
.should('include', 'totp=123');
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
|
||||
it('should allow logout active account', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] });
|
||||
it('should allow logout', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
@ -212,41 +139,116 @@ describe('multi account', () => {
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
cy.getByTestId('toolbar').should('contain', 'Join');
|
||||
});
|
||||
|
||||
it('should not allow log in the same account twice', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
describe('multi account', () => {
|
||||
it('should allow sign in with another account', () => {
|
||||
cy.login({ accounts: ['default2'] });
|
||||
|
||||
cy.visit('/');
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
|
||||
cy.get('[data-e2e-go-back]').should('exist');
|
||||
cy.get('[data-e2e-go-back]').should('exist');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 1);
|
||||
|
||||
cy.get('[data-e2e-account-id]')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
});
|
||||
|
||||
it('should go back to profile from login screen', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
|
||||
cy.get('[data-e2e-go-back]').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
|
||||
it('should allow logout active account', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
});
|
||||
|
||||
it('should not allow log in the same account twice', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
|
||||
cy.get('[data-e2e-go-back]').should('exist');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,51 +1,53 @@
|
||||
import { account1 } from '../../fixtures/accounts.json';
|
||||
|
||||
it('should send feedback', () => {
|
||||
const subject = 'Hello world';
|
||||
const message = 'This is a feedback message';
|
||||
describe('feedback popup', () => {
|
||||
it('should send feedback', () => {
|
||||
const subject = 'Hello world';
|
||||
const message = 'This is a feedback message';
|
||||
|
||||
cy.server();
|
||||
cy.route({
|
||||
url: '/api/feedback',
|
||||
method: 'POST',
|
||||
response: { success: true },
|
||||
cy.server();
|
||||
cy.route({
|
||||
url: '/api/feedback',
|
||||
method: 'POST',
|
||||
response: { success: true },
|
||||
});
|
||||
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('footer')
|
||||
.contains('Contact Us')
|
||||
.click();
|
||||
cy.getByTestId('feedbackPopup').should('be.visible');
|
||||
|
||||
cy.get('[name=subject]').type(subject);
|
||||
cy.get('[name=email]').should('have.value', account1.email);
|
||||
cy.get('[name=message]').type(message);
|
||||
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.getByTestId('select-label')
|
||||
.should('contain', 'What are you interested');
|
||||
cy.get('[data-e2e-select-name=category]').click();
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.contains('bug')
|
||||
.click();
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.getByTestId('select-label')
|
||||
.should('contain', 'bug');
|
||||
|
||||
cy.getByTestId('feedbackPopup')
|
||||
.get('[type=submit]')
|
||||
.click();
|
||||
|
||||
cy.getByTestId('feedbackPopup').should(
|
||||
'contain',
|
||||
'Your message was received',
|
||||
);
|
||||
cy.getByTestId('feedbackPopup').should('contain', account1.email);
|
||||
|
||||
cy.getByTestId('feedback-popup-close-button').click();
|
||||
|
||||
cy.getByTestId('feedbackPopup').should('not.be.visible');
|
||||
});
|
||||
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('footer')
|
||||
.contains('Contact Us')
|
||||
.click();
|
||||
cy.getByTestId('feedbackPopup').should('be.visible');
|
||||
|
||||
cy.get('[name=subject]').type(subject);
|
||||
cy.get('[name=email]').should('have.value', account1.email);
|
||||
cy.get('[name=message]').type(message);
|
||||
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.getByTestId('select-label')
|
||||
.should('contain', 'What are you interested');
|
||||
cy.get('[data-e2e-select-name=category]').click();
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.contains('bug')
|
||||
.click();
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.getByTestId('select-label')
|
||||
.should('contain', 'bug');
|
||||
|
||||
cy.getByTestId('feedbackPopup')
|
||||
.get('[type=submit]')
|
||||
.click();
|
||||
|
||||
cy.getByTestId('feedbackPopup').should(
|
||||
'contain',
|
||||
'Your message was received',
|
||||
);
|
||||
cy.getByTestId('feedbackPopup').should('contain', account1.email);
|
||||
|
||||
cy.getByTestId('feedback-popup-close-button').click();
|
||||
|
||||
cy.getByTestId('feedbackPopup').should('not.be.visible');
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user