我正在使用@auth0/auth0-spa-js隐藏在Auth0锁后面的单页应用程序。我想使用赛普拉斯对其进行测试,所以我决定遵循官方的Auth0 blog post和约翰尼·赖利blog post。
我能够使用建议的请求从auth0成功检索有效的JWT令牌。我不知道该怎么办:(
我面临的麻烦是以上两种方法都依赖于应用程序在本地存储JWT令牌(以cookie或localstorage形式)。 @auth0/auth0-spa-js使用的是另一种方法,我假设所有相关的cookie /本地存储都存储在auth0域中。
您有什么想法,是否有办法解决?
据报here于2018年7月提出了类似问题,但并未提供任何解决方案
答案 0 :(得分:3)
我在@auth0/auth0-spa-js
的github上找到了已解决的问题。 approach建议的cwmrowe似乎有效
解决方案是使用在e2e测试端生成的令牌来模拟oauth/token
端点的响应。
这种方法似乎对我们有用
我正在复制提供的示例代码cwmrowe
Cypress.Commands.add(
'login',
(username, password, appState = { target: '/' }) => {
cy.log(`Logging in as ${username}`);
const options = {
method: 'POST',
url: Cypress.env('Auth0TokenUrl'),
body: {
grant_type: 'password',
username,
password,
audience: Cypress.env('Auth0Audience'),
scope: 'openid profile email',
client_id: Cypress.env('Auth0ClientId'),
client_secret: Cypress.env('Auth0ClientSecret')
}
};
cy.request(options).then(({ body }) => {
const { access_token, expires_in, id_token } = body;
cy.server();
// intercept Auth0 request for token and return what we have
cy.route({
url: 'oauth/token',
method: 'POST',
response: {
access_token,
expires_in,
id_token,
token_type: 'Bearer'
}
});
// Auth0 SPA SDK will check for value in cookie to get appState
// and validate nonce (which has been removed for simplicity)
const stateId = 'test';
const encodedAppState = encodeURI(JSON.stringify(appState));
cy.setCookie(
`a0.spajs.txs.${stateId}`,
`{%22appState%22:${encodedAppState}%2C%22scope%22:%22openid%20profile%20email%22%2C%22audience%22:%22default%22}`
);
const callbackUrl = `/auth/callback?code=test-code&state=${stateId}`;
return cy.visit(callbackUrl);
});
}
);
declare namespace Cypress {
interface Chainable<Subject> {
login(
username: string,
password: string,
appState?: any
): Chainable<Subject>;
}
}
答案 1 :(得分:0)
虽然不建议使用UI登录,但在进行所有测试之前,我自己做一次,然后对测试使用静默身份验证:-cy.visit("/")
静默身份验证并允许访问应用程序。
integration / app.js
describe("App", () => {
before(() => {
Cypress.config("baseUrl", "http://localhost:3000");
cy.login();
});
/** Uses silent auth for successive tests */
beforeEach(() => {
cy.restoreLocalStorage();
});
afterEach(() => {
cy.saveLocalStorage();
});
/** tests */
support / commands.js
/**
* Auth0 login
* https://github.com/cypress-io/cypress/issues/461#issuecomment-392070888
*
* Allows silent auth login between tests
*/
let LOCAL_STORAGE_MEMORY = {};
Cypress.Commands.add("saveLocalStorage", () => {
Object.keys(localStorage).forEach(key => {
LOCAL_STORAGE_MEMORY[key] = localStorage[key];
});
});
Cypress.Commands.add("restoreLocalStorage", () => {
Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
});
});
Cypress.Commands.add("clearLocalStorage", () => {
LOCAL_STORAGE_MEMORY = {};
});
答案 2 :(得分:0)
对于那些对于赛普拉斯的Google登录有问题的人,请查看插件:https://github.com/lirantal/cypress-social-logins/
it('Login through Google', () => {
const username = Cypress.env('googleSocialLoginUsername')
const password = Cypress.env('googleSocialLoginPassword')
const loginUrl = Cypress.env('loginUrl')
const cookieName = Cypress.env('cookieName')
const socialLoginOptions = {
username,
password,
loginUrl,
headless: false,
isPopup: true,
logs: false,
loginSelector: 'a[href="/auth/auth0/google-oauth2"]',
postLoginSelector: '.account-panel'
}
return cy.task('GoogleSocialLogin', socialLoginOptions).then(({cookies}) => {
cy.clearCookies()
const cookie = cookies.filter(cookie => cookie.name === cookieName).pop()
if (cookie) {
cy.setCookie(cookie.name, cookie.value, {
domain: cookie.domain,
expiry: cookie.expires,
httpOnly: cookie.httpOnly,
path: cookie.path,
secure: cookie.secure
})
Cypress.Cookies.defaults({
whitelist: cookieName
})
}
})
});