如何使用cy.origin()测试无公开页面的OAuth认证应用?
解决无公开页面的OAuth应用Cypress测试报错问题
问题背景
测试无公开页面的OAuth保护应用时,未认证用户访问任意路由都会直接跳转到OAuth服务器。使用Cypress编写测试时,调用cy.origin()出现如下报错:
CypressError:
cy.origin()requires the first argument to be a different domain than top. You passedhttp://fake-oauth-server:5001to the origin command, while top is athttp://fake-oauth-server:5001.Either the intended page was not visited prior to running the cy.origin block or the cy.origin block may not be needed at all.
模拟环境
- 假应用运行在
fake-app:5000 - 假OAuth服务器运行在
fake-oauth-server:5001
模拟代码
假应用代码(Flask)
from flask import Flask, redirect, render_template_string app = Flask(__name__) app_host="fake-app" app_port=5000 app_uri=f"http://{app_host}:{app_port}" oauth_host="fake-oauth-server" oauth_port=5001 oauth_uri=f"http://{oauth_host}:{oauth_port}" @app.route('/') def hello(): return render_template_string('''<!doctype html> <html> <body> <p>Hello, World MainApp!</p> <a id="loginButton" href="{{ oauth_uri }}?redirect_uri={{ app_uri }}">Login</a> </body> </html> ''', oauth_uri=oauth_uri, app_uri=app_uri ) @app.route('/goto-oauth') def goto_oauth(): return redirect(f"{oauth_uri}?redirect_uri={app_uri}") if __name__ == '__main__': app.run(host=app_host, port=app_port)
假OAuth服务器代码(Flask)
from flask import Flask, render_template_string, request app = Flask(__name__) oauth_host="fake-oauth-server" oauth_port=5001 @app.route('/') def login(): return render_template_string( '''<!doctype html> <html> <body> <p>Please log in</p> <label>Username: <label><input id="username" /> <label>Password: <label><input id="password" /> <a id="submit-password" href="{{ redirect_uri }}">Submit</a> </body> </html> ''', redirect_uri=request.args.get('redirect_uri')) if __name__ == '__main__': app.run(host=oauth_host, port=oauth_port)
问题测试代码
describe('My Scenarios', () => { beforeEach(() => { cy.visit('/goto-oauth'); cy.origin('http://fake-oauth-server:5001', () => { cy.contains('Please log in'); cy.get('input#username').type('user1'); cy.get('input#password').type('password1'); cy.get('a#submit-password').click() }); }); it.only('test flask', () => { cy.visit('/'); cy.contains('MainApp'); }); });
解决方案
报错原因是:cy.visit('/goto-oauth')执行后,浏览器会自动跳转到OAuth服务器,此时Cypress的测试上下文已经处于OAuth域名下,再调用cy.origin()传入相同域名就会触发错误。
修改后的测试代码如下,直接在当前上下文执行登录操作,无需cy.origin():
describe('My Scenarios', () => { beforeEach(() => { // 访问触发跳转的路由 cy.visit('/goto-oauth'); // 等待页面完成跳转,并验证当前域名是OAuth服务器 cy.location('origin').should('eq', 'http://fake-oauth-server:5001'); // 直接执行登录操作 cy.contains('Please log in'); cy.get('input#username').type('user1'); cy.get('input#password').type('password1'); cy.get('a#submit-password').click(); // 等待跳转回应用,并验证域名 cy.location('origin').should('eq', 'http://fake-app:5000'); }); it.only('test flask', () => { cy.visit('/'); cy.contains('MainApp'); }); });
关键说明
- 跳转验证:通过
cy.location('origin')的断言,确保页面完成跳转后再执行后续步骤,避免因页面加载延迟导致的元素找不到问题。 - 无需
cy.origin():当测试上下文已经处于目标域名时,直接操作元素即可,cy.origin()仅用于从当前域名切换到其他域名的场景。
如果应用是访问根路径/时直接跳转,测试代码逻辑完全一致,只需将cy.visit('/goto-oauth')改为cy.visit('/')即可。
内容的提问来源于stack exchange,提问作者Lesiak
相关产品推荐
相关产品推荐

