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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM