zoukankan      html  css  js  c++  java
  • Cypress web自动化20-a标签超链接跨域问题

    前言

    cypress 上默认访问一个跨域的网页会出现异常:
    Cypress detected a cross origin error happened on page load
    A cross origin error happens when your application navigates to a new URL which does not match the origin policy above.
    之前使用 selenium 的时候,不用关心这种问题,a标签点击后会跳转到另外一个web页面,正常使用。
    cypress上对web的安全性上考虑的更严格,对于跨域的链接会认为是不安全的,相关的资料查阅https://docs.cypress.io/guides/guides/web-security.html

    a标签

    当访问一个web页面,点如下按钮时

    a标签的 html 元素内容如下

    <p>
       <a id="yoyoketang" href="https://www.cnblogs.com/yoyoketang/">点这里跳转到我的博客</a>
    </p>
    

    本来我的项目部署在 http://localhost:8000,但是这个链接是 https://www.cnblogs.com,接下来看使用 cypress 脚本点击会发生什么情况

    // # 上海-悠悠,QQ交流群:750815713
    
    describe('a标签跨域问题', function() {
        beforeEach(() => {
              cy.visit('http://localhost:8000/yoyoketang/')
    
            })
    
        it("a标签测试", () =>
        {
            // 输入用户名
            cy.get("a#yoyoketang")
                .click()
        })
        })
    

    运行结果

    报错内容

    Cypress detected a cross origin error happened on page load:
    
      > Blocked a frame with origin "http://localhost:8000" from accessing a cross-origin frame.
    
    Before the page load, you were bound to the origin policy:
    
      > http://localhost:8000
    
    A cross origin error happens when your application navigates to a new URL which does not match the origin policy above.
    
    A new URL does not match the origin policy if the 'protocol', 'port' (if specified), and/or 'host' (unless of the same superdomain) are different.
    
    Cypress does not allow you to navigate to a different origin URL within a single test.
    
    You may need to restructure some of your test code to avoid this problem.
    
    Alternatively you can also disable Chrome Web Security in Chromium-based browsers which will turn off this restriction by setting { chromeWebSecurity: false } in cypress.json
    

    用例设计

    由于 cypress 会在浏览器拒绝在安全页面上显示不安全的内容,因为Cypress最初将URL更改为与http://localhost:8000匹配,当浏览器跟随href到https://www.cnblogs.com时,浏览器将拒绝显示内容。
    你可能会觉得这是 cypress 的缺陷,很多人会觉得之前用 selenium 都可以,然而,事实是,Cypress在你的应用程序中暴露了一个安全漏洞,你希望它在Cypress中失败。
    没有将secure标志设置为true的cookies将作为明文发送到不安全的URL。这使得你的应用程序很容易受到会话劫持。
    即使你的web服务器强制301重定向回HTTPS站点,此安全漏洞仍然存在。原始HTTP请求仍然发出一次,暴露了不安全的会话信息。
    解决办法:只需更新HTML或JavaScript代码,不导航到不安全的HTTP页面,而是只使用HTTPS。另外,请确保cookie的secure标志设置为true。

    事实上我们没有任何理由访问测试中无法控制的站点。它容易出错,速度很慢。
    相反,你只需要测试href属性是否正确!

    // # 上海-悠悠,QQ交流群:750815713
    
    describe('a标签跨域问题', function() {
        beforeEach(() => {
              cy.visit('http://localhost:8000/yoyoketang/')
    
            })
    
        it("a标签测试", () =>
        {
            // a标签href属性
            cy.get("a#yoyoketang")
                .should('have.attr', 'href', 'https://www.cnblogs.com/yoyoketang/')
        })
        })
    

    这时你会担心 https://www.cnblogs.com/yoyoketang/提供正确的HTML内容。你会怎么测试呢?
    简单!只需直接向它发送一个cy.request()不绑定到CORS或同源策略。cy.request()很特殊,因为它不绑定到CORS或同源策略。

    // # 上海-悠悠,QQ交流群:750815713
    
    describe('a标签跨域问题', function() {
        beforeEach(() => {
              cy.visit('http://localhost:8000/yoyoketang/')
    
            })
    
        it("a标签测试", () =>
        {
            // a标签href属性
            cy.get("a#yoyoketang")
                .should('have.attr', 'href', 'https://www.cnblogs.com/yoyoketang/')
            cy.get('a').then(($a) => {
                // 从<a>中取出完全限定的href
                const url = $a.prop('href')
    
                // 向它发起cy.request
                cy.request(url)
                    .its('body')
                    .should('include', '</html>')
                    .should('include', '上海-悠悠')
            })
        })
        })
    

    还不满意吗?你真的想点击进入另一个应用程序吗?好的,那么请阅读关于 "禁用web安全" 的内容。

    禁用web安全

    回到上面报错的内容最后一行:
    Alternatively you can also disable Chrome Web Security in Chromium-based browsers which will turn off this restriction by setting { chromeWebSecurity: false } in cypress.json
    如果你想让浏览器禁用web安装,需在cypress.json中加个配置

    {"chromeWebSecurity": false }
    

    接着再运行之前的代码,就不会报错了

    // # 上海-悠悠,QQ交流群:750815713
    
    describe('a标签跨域问题', function() {
        beforeEach(() => {
              cy.visit('http://localhost:8000/yoyoketang/')
    
            })
    
        it("a标签测试", () =>
        {
            // 输入用户名
            cy.get("a#yoyoketang")
                .click()
        })
        })
    

    首先,你需要了解并非所有浏览器都提供关闭web安全的方法。有些浏览器提供,一般chrome浏览器上是可以的,有些不提供。
    如果你依赖于禁用web安全,你将无法在不支持此功能的浏览器上运行测试。

    设置chromeWebSecurity为false允许你做以下事情:

    • 显示不安全的内容
    • 导航到任何超域没有跨域错误
    • 访问嵌入到应用程序中的跨域iframe。

    不过,你可能会注意到,Cypress仍然强制使用cy.visit()访问单个超域,也就是以下基本是不支持的

    // # 上海-悠悠,QQ交流群:750815713
    describe('跨域问题', function() {
    
          it("test case:跨域 ", ()=>{
    
              cy.visit('https://www.baidu.com/');
              cy.visit("https://www.cnblogs.com/yoyoketang/")
    
          })
        
        })
    

    但是有一个 issue https://github.com/cypress-io/cypress/issues/944可以更改这个限制。
    QQ交流群:939110556

  • 相关阅读:
    QtDBus快速入门
    论Qt容器与STL
    JS中的!=、== 、!==、===的用法和区别
    JS操作JSON总结
    select2使用方法总结
    Entity Framework插入数据报错:Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
    Windows登录类型及安全日志解析
    <script type="text/html"></script> js模版使用
    在 C# 中,(int) ,Int32.Parse() 和 Convert.toInt32() 三种方法的区别
    关于session,cookie,Cache
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/12929779.html
Copyright © 2011-2022 走看看