cy.origin() 和立即重定向

Les*_*iak 4 cypress cypress-origin

我在测试受 oauth 保护的应用程序时遇到问题。当没有公共页面时,问题就会显现出来 - 如果用户未经过身份验证,就会立即重定向到 OAuth 服务器。

我设法以更简单的设置重现该问题:

  • 在 fake-app 域中运行的假应用程序
  • 在 fake-oauth-server 域中运行的假 oauth 服务器

以下是各自的应​​用程序(在 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)
Run Code Online (Sandbox Code Playgroud)

假oauth服务器:

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)
Run Code Online (Sandbox Code Playgroud)

第一个流程:有一个带有登录按钮的公开页面

可以使用 cy.origin 进行测试:

describe('My Scenarios', () => {
  beforeEach(() => {
    cy.visit('/');
    cy.contains('MainApp');
    cy.get('a#loginButton').click();
    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');
  });
});
Run Code Online (Sandbox Code Playgroud)

有问题的流程:立即重定向到 Oauth 服务器

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');
  });
});
Run Code Online (Sandbox Code Playgroud)

失败:

CypressError: `cy.origin()` requires the first argument to be a different domain than top. You passed `http://fake-oauth-server:5001` to the origin command, while top is at `http://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.
Run Code Online (Sandbox Code Playgroud)

我的应用程序中没有公开可用的页面 - 我如何修改测试以使其正常工作?

Fod*_*ody 5

如果访问cy.origin().

我使用express而不是flask设置应用程序http://localhost:6001和身份验证服务器。http://localhost:6003

测试

describe('My Scenarios', () => {
  beforeEach(() => {
    cy.origin('http://localhost:6003', () => {
      cy.visit('http://localhost:6001/goto-oauth')
      cy.contains('Please log in');
      cy.get('input#username').type('user1');
      cy.get('input#password').type('password1');
      cy.get('a#submit-password').click()
    });
  });

  it('test main app', () => {
    cy.visit('http://localhost:6001')
    cy.contains('MainApp')
  })
})
Run Code Online (Sandbox Code Playgroud)

应用程序

const express = require('express')
function makeApp() {
  const app = express()
  app.get('/', function (req, res) {
    res.send(`
      <html>
      <body>
        <p>Hello, World MainApp!</p>
        <a id="loginButton" href="http://localhost:6003?redirect_uri=http://localhost:6001">
          Login
        </a>
      </body>
      
      </html>
    `)
  })
  app.get('/goto-oauth', function (req, res) {
    res.redirect('http://localhost:6003')
  })

  const port = 6001

  return new Promise((resolve) => {
    const server = app.listen(port, function () {
      const port = server.address().port
      console.log('Example app listening at port %d', port)

      // close the server
      const close = () => {
        return new Promise((resolve) => {
          console.log('closing server')
          server.close(resolve)
        })
      }

      resolve({ server, port, close })
    })
  })
}

module.exports = makeApp
Run Code Online (Sandbox Code Playgroud)

授权

const express = require('express')
function makeServer() {
  const app = express()
  app.get('/', function (req, res) {
    res.send(`
    <!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="http://localhost:6001">Submit</a>
        </body>
    </html>
    `)
  })

  const port = 6003

  return new Promise((resolve) => {
    const server = app.listen(port, function () {
      const port = server.address().port
      console.log('Example app listening at port %d', port)

      // close the server
      const close = () => {
        return new Promise((resolve) => {
          console.log('closing server')
          server.close(resolve)
        })
      }

      resolve({ server, port, close })
    })
  })
}

module.exports = makeServer
Run Code Online (Sandbox Code Playgroud)