我在 Cypress 中为受 Keycloak 保护的 Web 应用程序编写了自动化测试。我已经设法从 keycloak 检索 jwt 令牌,但我不知道如何处理它。我已经看到,在您登录 keycloak 后,您被重定向到您的域,并且 keyclock 设置了 cookie、本地存储等。 当您登录他们的页面时,有没有办法以编程方式获得与 keyclock 相同的结果?换句话说,有类似的东西:
cy.getToken().then((token) => {
cy.login(token);
cy.visit(myDomain)
})
答案 0 :(得分:4)
看看图书馆,cypress-keycloak-commands 是另一个更受欢迎的图书馆(大约是每周下载量的三倍)。
我喜欢它基于配置的方式,并且有 cy.kcFakeLogin()
用于基于夹具的模拟。
如果您想了解 Keycloak 的详细信息,还有此博客 Cypress.io Keycloak Integration。
如果链接消失,请转载以备将来参考
Cypress.Commands.add('kcLogin', (username, password) => {
const kcRoot = 'http://my.keycloak.com';
const kcRealm = 'MYrealm';
const kcClient = 'my-client';
const kcRedirectUri = 'http://localhost:3000/';
const loginPageRequest = {
url: `${kcRoot}/auth/realms/${kcRealm}/protocol/openid-connect/auth`,
qs: {
client_id: kcClient,
redirect_uri: kcRedirectUri,
state: createUUID(),
nonce: createUUID(),
response_mode: 'fragment',
response_type: 'code',
scope: 'openid'
}
};
// Open the KC login page, fill in the form with username and password and submit.
return cy.request(loginPageRequest)
.then(submitLoginForm);
////////////
function submitLoginForm(response) {
const _el = document.createElement('html');
_el.innerHTML = response.body;
// This should be more strict depending on your login page template.
const loginForm = _el.getElementsByTagName('form');
const isAlreadyLoggedIn = !loginForm.length;
if (isAlreadyLoggedIn) {
return;
}
return cy.request({
form: true,
method: 'POST',
url: loginForm[0].action,
followRedirect: false,
body: {
username: username,
password: password
}
});
}
// Copy-pasted code from KC javascript client. It probably doesn't need to be
// this complicated but I refused to spend time on figuring that out.
function createUUID() {
var s = [];
var hexDigits = '0123456789abcdef';
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = '4';
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = '-';
var uuid = s.join('');
return uuid;
}
});
答案 1 :(得分:1)
再次遇到这个问题。和 Boogie 一样,我们一直无法让 cypress.io 登录 keycloak。
有没有人在 Keycloak 和 Cypress.io 上取得过任何成功?我已经尝试了任何和所有的建议。我们在前端使用 Angular(8.2.14 版)、Keycloak(11.0.3 版)和 Cypress.io(7.3.0 版)。
尝试过但失败了:
cypress-keycloak 和 cypress-keycloak-command 库
此处找到的步骤https://vrockai.github.io/blog/2017/10/28/cypress-keycloak-intregration/
我们正在尝试什么:
使用visit()从keycloak获取登录页面,然后重定向false(成功)。
向我们自己的服务器发送身份验证请求并遵循重定向错误(成功)。
在 keycloak 页面提交登录凭据,点击登录按钮并等待(成功,因为我们可以在 keycloak 服务上看到用户已成功登录且没有错误)。
重定向到 Angular 站点永远不会发生。
使用任何浏览器手动执行登录步骤,效果很好。
我的智商已经不行了。欢迎提出任何建议。
答案 2 :(得分:0)
您可以使用插件 cypress-keycloak 来实现这一点。
安装后转到 cypress/support/commands.js
并写入:
// Using ES6
import 'cypress-keycloak';
OR
// using CommonJS
require('cypress-keycloak');
然后在您的测试中您可以编写(示例取自 cypress-keycloak npm 页面):
describe('thing', () => {
beforeEach(() => {
cy.login({
root: 'https://keycloak.babangsund.com',
realm: 'stage',
username: 'babangsund',
password: 'bacon',
client_id: 'frontend',
redirect_uri: 'https://babangsund.com/',
});
// or login with OTP
cy.loginOTP({
root: 'https://keycloak.babangsund.com',
realm: 'stage',
username: 'babangsund',
password: 'bacon',
client_id: 'frontend',
redirect_uri: 'https://babangsund.com/',
otp_secret: 'OZLDC2HZKM3QUC...', // e.g. 32 chars
otp_credential_id: '5e231f20-8ca7-35e1-20a694b60181ca9', // e.g. 36 chars
});
});
afterEach(() => {
cy.logout({
root: 'https://keycloak.babangsund.com',
realm: 'stage',
redirect_uri: 'https://babangsund.com/',
});
});
});