Cypress web automation 20-a tag hyperlink cross-domain issue

Foreword

By default, accessing a cross-domain webpage on cypress will cause an exception:
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.
When using selenium before, you don’t have to worry about this problem. After clicking on the a tag, it will jump to another web page and can be used normally.
Cypress considers web security more strictly and considers cross-domain links to be unsafe. For relevant information, please refer to https://docs.cypress.io/guides/guides/web-security.html.

a tag

When visiting a web page, click the following button outline: none;”>
The content of the html element of the a tag is as follows

<p>
   <a id="yoyoketang" href="https://www.cnblogs.com/yoyoketang/">Click here to jump to my blog</a>
</p>

Originally, my project was deployed at http://localhost:8000, but the link is https://www.cnblogs.com. Next, let’s see how to use the cypress script to click. what happened

// # Shanghai-Youyou, QQ communication group: 750815713

describe('a tag cross-domain issue', function() {
    beforeEach(() => {
          cy.visit('http://localhost:8000/yoyoketang/')

        })

    it("a label test", () =>
    {
        // Enter your user name
        cy.get("a#yoyoketang")
            .click()
    })
    })

Running results

Error content

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

Use case design

The browser refuses to display insecure content on secure pages because Cypress initially changes the URL to match http://localhost:8000 when the browser follows the href to https://www.cnblogs.com , the browser will refuse to display the content.
You may think this is a flaw of cypress. Many people will think that they can use selenium before. However, the fact is that Cypress exposes a security vulnerability in your application and you want it to fail in Cypress.
Cookies without the secure flag set to true will be sent as clear text to unsecured URLs. This makes your application vulnerable to session hijacking.
Even if your web server forces a 301 redirect back to an HTTPS site, this security hole still exists. The original HTTP request is still issued once, exposing insecure session information.
Solution: Simply update the HTML or JavaScript code to not navigate to insecure HTTP pages and only use HTTPS. Also, make sure the cookie’s secure flag is set to true.

In fact we have no reason to visit sites that are beyond our control in the test. It’s error-prone and slow.
Instead, you just need to test that the href attribute is correct!

// # Shanghai-Youyou, QQ communication group: 750815713

describe('a tag cross-domain issue', function() {
    beforeEach(() => {
          cy.visit('http://localhost:8000/yoyoketang/')

        })

    it("a label test", () =>
    {
        // a tag href attribute
        cy.get("a#yoyoketang")
            .should('have.attr', 'href', 'https://www.cnblogs.com/yoyoketang/')
    })
    })

At this time you will worry about https://www.cnblogs.com/yoyoketang/ providing correct HTML content. How would you test this?
Simple! Just send it a cy.request() directly without binding to CORS or the same origin policy. cy.request() is special in that it is not bound to CORS or the same origin policy.

// # Shanghai-Youyou, QQ communication group: 750815713

describe('a tag cross-domain issue', function() {
    beforeEach(() => {
          cy.visit('http://localhost:8000/yoyoketang/')

        })

    it("a label test", () =>
    {
        // a tag href attribute
        cy.get("a#yoyoketang")
            .should('have.attr', 'href', 'https://www.cnblogs.com/yoyoketang/')
        cy.get('a').then(($a) => {
            // Get the fully qualified href from <a>
            const url = $a.prop('href')

            // Initiate cy.request to it
            cy.request(url)
                .its('body')
                .should('include', '</html>')
                .should('include', 'Shanghai-Yuyou')
        })
    })
    })

Not satisfied yet? Do you really want to click into another app? Okay, so please read about “Disabling web security”.

Disable web security

Go back to the last line of the error message above:
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
If you want the browser to disable web installation, you need to add a configuration in cypress.json

{"chromeWebSecurity": false }

Then run the previous code and no error will be reported.

// # Shanghai-Youyou, QQ communication group: 750815713

describe('a tag cross-domain issue', function() {
    beforeEach(() => {
          cy.visit('http://localhost:8000/yoyoketang/')

        })

    it("a label test", () =>
    {
        // Enter your user name
        cy.get("a#yoyoketang")
            .click()
    })
    })

First, you need to understand that not all browsers offer a way to turn off web security. Some browsers provide it, generally it is available on chrome browsers, but some do not.
If you rely on disabling web security, you will not be able to run tests on browsers that do not support this feature.

Setting chromeWebSecurity to false allows you to do the following:

  • Show unsafe content
  • Navigate to any superdomain without cross-domain errors
  • Access a cross-domain iframe embedded in the application.

However, you may notice that Cypress still forces the use of cy.visit() to access a single superdomain, which means that the following is basically not supported

// # Shanghai-Youyou, QQ communication group: 750815713
describe('Cross-domain problem', function() {

      it("test case:cross domain ", ()=>{

          cy.visit('https://www.baidu.com/');
          cy.visit("https://www.cnblogs.com/yoyoketang/")

      })
    
    })

But there is an issue https://github.com/cypress-io/cypress/issues/944 that can change this limit. QQ communication group: 939110556