Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change baseUrl during test (set to null) in order to visit local file instead of URL #2918

Closed
dhmoon91 opened this issue Dec 10, 2018 · 26 comments · Fixed by #18589
Closed
Assignees
Labels
type: enhancement Requested enhancement of existing feature

Comments

@dhmoon91
Copy link

dhmoon91 commented Dec 10, 2018

Current behavior:

We are currently implementing email confirmation test.
We currently download the email file -> parse out the html content of it -> save it locally in fixture/.

In order for cypress.visit('path-to-local-file.html') to load up the downloaded content, we need to change the baseUrl that was set in cypress.json to be empty.

Cypress.config('baseUrl', ' ');doesn't switchbaseUrland keeps appending the path to local file to the originalbaseUrl`, eg: https://demo.test.com/fixtures/email-content.html

Also tried to follow https://docs.cypress.io/api/plugins/configuration-api.html#Usage but it also fails to switch out baseUrl.

I couldn't find any workaround.

One method I tried was NOT setting baseUrl in cypress.json and specify the main domain everywhere except for visiting local html file. But this also fails because we have a before hook that generates unique string for email and if you change the domain on cy.visit(), the before hook runs and the email file name won't match.

Desired behavior:

Cypress.config('baseUrl', ' '); should switch baseUrl to none.

Steps to reproduce: (app code and test code)

Posting it as pseudo-code. Will fill in more details if needed.

cypress.json

{
    "baseUrl": "https://demo.testing.com",
    "userAgent": "testing"
}

test spec file

 var emailFileName;

    before(function () {
        cy.log('ran');
        cy.task('generateGuid').then(function ($guid) {
            guid = $guid;
            emailFileName = 'tester' + guid + '@test.com';
            cy.log(emailText);
        });
    });

it('Register user', function () {

        cy.visit('/login'); //-> yields https://demo.testing.com/login
        // Fill up registration info then click 'Register' button

        cy.wait(5000);
        cy.get(sendConfirmEmailButton).click({ force: true });

        // wait for 30s to verify email body
        cy.wait(20000);
        cy.downloadEmailHtml(emailFileName, 'confirmAccount');
    });

it('Visit email user', function () {
        // Change baseurl
        Cypress.config('baseUrl', ' ');
        // TODO visit/load the confirm account html file
        cy.visit(`cypress/fixtures/confirmAccount_${emailFileName}@test.com.html`);
        cy.get('#templateBody')
            .contains('Click the button below to confirm your account');
    });

Versions

Cypress: 3.1.3
OS: Mac- mojave

@dhmoon91
Copy link
Author

I kinda went all over the place but really, I just need to set the baseUrl to empty or null to load up the local html content file and I thought the Cypress.configure('baseUrl', '') would support this behaviour.

@jennifer-shehane

This comment has been minimized.

@jennifer-shehane jennifer-shehane added the stage: awaiting response Potential fix was proposed; awaiting response label Dec 10, 2018
@dhmoon91
Copy link
Author

Hi @jennifer-shehane .

Thanks for the qucik reply .

I just tried setting it null and Cypress seems to append localhost + random port infront of the cypress/fixtures/confirmAccount_${emailFileName}@test.com.html.

For me, cypress tries to visithttp://localhost:60465/cypress/fixtures/confirmAccount_${emailFileName}@test.com.html
and fails.

This might be related to #382?

@dhmoon91

This comment has been minimized.

@jennifer-shehane jennifer-shehane added stage: needs investigating Someone from Cypress needs to look at this and removed stage: awaiting response Potential fix was proposed; awaiting response labels Jan 3, 2019
@you1anna
Copy link

you1anna commented Jun 10, 2019

Any updates on this issue? It is undesirable behaviour:

Cypress.Commands.add("loginToRm", (email, password) => {
    Cypress.config('baseUrl', null)
    cy.visit(Cypress.env('rmBaseUrl'))
        .get(RM_EMAIL_FIELD).type(email)
        .get(RM_PASSWORD_FIELD).type(password)
        .get(RM_LOGIN_BUTTON).click()
        .url().should('contain', '/admin/Home')
});

The above will redirect to baseUrl in Cypress.config instead of remaining at rmBaseUrl. The alternative is to never set baseUrl in the main config, against best practise.

An update on a fix or workaround would be greatly appreciated.

@pmn4
Copy link

pmn4 commented Jun 21, 2019

I am experiencing something similar:
I have several applications on subdomains which redirect to a relative path (client-side) once an authentication request succeeds (that is, the user should stay on the subdomain once they authenticate). I am testing all applications in a single suite, so I set baseUrl as "baseUrl": "domain.com" in cypress.json since "domain.com" is the superdomain for all applications.

I have tried setting Cypress.config("baseUrl", "stage.domain.com") and Cypress.config("baseUrl", null), but in either case, the page redirects to www.domain.com/home instead of stage.domain.com/home

image

The yellow arrow shows that my baseUrl is "domain.com"
The blue arrow points to my application's subdomain
The red arrow shows where an AJAX authentication attempt succeeds and the user is redirected using window.location.redirect("/home"). This translates to "www.domain.com/home" (our server configuration points all naked domain requests to www.)

unsetting baseUrl in my config works for the first subdomain that is visited, but subsequent subdomains do not (as latter subdomains do not descend from the first).

@jennifer-shehane jennifer-shehane added the type: enhancement Requested enhancement of existing feature label Nov 5, 2019
@jennifer-shehane jennifer-shehane changed the title Changing baseUrl during test Change baseUrl during test (set to null) in order to visit local file instead of URL Nov 5, 2019
@mbatesR
Copy link

mbatesR commented Nov 14, 2019

@jennifer-shehane Can you elaborate on why the baseURL reassignment during a test isn't applying? I have ran into cases as well where I needed to change the base URL mid-test to set key:value pairs in local storage and wasn't able to.

@zhammer
Copy link

zhammer commented Dec 16, 2019

may not work for everyone, but since i'm using cypress to test a python web application that serves up everything in a static/ directory, i've done this:

const html = /* my html */;
cy.writeFile("static/tempfile.html", html);
cy.visit("static/tempfile.html");

@jennifer-shehane
Copy link
Member

@mbatesR Cypress changes the parent domain to match the baseUrl, in order to avoid issues with navigating on a website that does not match the parent domain. The Cypress product is just not coded to handle changing the baseUrl mid test.

@mihaic195
Copy link

@jennifer-shehane I think the inability to change the baseUrl mid test is a problem in our case.

Currently I am facing an issue where I do a login using API requests with cy.request. Login is happening on Auth0. This is needed to retrieve some JWTs from Auth0 and setting necessary cookies in the browser. This is needed for cross-domain authentication (SSO). Everything ok until here.

After setting the necessary cookies, I navigate to the page which I want to test using cy.visit. Doing any sort of interaction on that page causes the browser to reload and breaks the tests.
Possibly the exact same situation: #2542
I did not set any baseUrl because of the following:

We have pre-production environments where subdomains are dynamic and also certain parts of the application redirect to other subdomains.

For example x.subdomain1.domain.com can redirect to x.subdomain2.domain.com, where subdomain1 and subdomain2 can be seen as bounded contexts of the application, while x is a github branch identifier.

I think a fix for this is to at least allow for some sort of wildcard in the baseUrl or regex?

A workaround can be to actually do the login during the test, click on login -> enter user/pass -> click login etc. But it is actually something that we want to avoid in the first place, as it causes tests to run for a longer time and it shouldn't be part of the actual test IMHO.

What do you suggest in this case?

@jennifer-shehane
Copy link
Member

@mihaic195 I'm not completely sure of the circumstance you're describing.

Doing any sort of interaction on that page causes the browser to reload and breaks the tests.

I have an example below where the cookies set before and after visit are both set. It's likely more complicated than my example, so I'd like to understand. Can you provide an example of how the tests are failing due to the browser reload?

it('setting cookies when no baseUrl', () => {
  cy.setCookie('foo', 'bar')

  cy.visit('https://example.cypress.io')
  
  cy.setCookie('baz', 'fizz')
  cy.getCookies().then((cookies) => {
    expect(cookies[1]).to.have.property('name', 'foo')
    expect(cookies[2]).to.have.property('name', 'baz')
  })
})

@mihaic195
Copy link

mihaic195 commented Mar 31, 2020

@jennifer-shehane I'll try to explain below.

Basically the tests are failing exactly how you see in the video of #2542

Steps:

  1. Create a custom cypress login command, which creates a cy.request on an Auth0 link and sets the appropriate cookies in the browser (access_token, id_token, expires_at).
  2. Visit the protected resource of our application using cy.visit, which requires the cookies to be set with the right values, otherwise you wouldn't be able to access the resource.
  3. After arriving on the page, I do a cy.contains('Share').click() which is supposed to open a modal and do some actions on that modal.
  4. Upon clicking on the button from step 3, the modal briefly opens and then the browser refreshes, which brings us back to step 2 and then since the modal is not open anymore, it cannot continue with the remaining code of the test. It would need to do cy.contains('Share').click() again to re-open the modal.

Normally I should be able to set baseUrl to x.subdomain1.domain.com and it should work (based on the answers from #2542), but even by setting the baseUrl, the browser is still refreshed so maybe I am missing something.
Basically I am doing a cy.request to an Auth0 domain and a cy.visit to our application.

In any case, our test suite contains tests which are also part of other subdomains, such as x.subdomain2.domain.com, which brings us back to the problem of the current issue, so the baseUrl will not be correct for other tests, that's why I thought having a wildcard/regex as a baseUrl would be beneficial.

If I login using the test itself, the flow would be something like:

  1. Click on Login button
  2. Be redirected to Auth0 URL
  3. Type the user/pass
  4. Submit form
  5. Be redirected to the protected resource of our application

This flow works fine. This case doesn't include any cy.request and cy.visit. But as I said, I feel that this part should not be part of the context of the test itself from a business logic point of view, but also because it increases the time spent during the test, that's why I even created a custom login command to begin with.

I am running the tests using the docker image provided by Cypress (https://www.cypress.io/blog/2019/05/02/run-cypress-with-a-single-docker-command/)

Was it clear enough?
Thanks.

@andrei22b
Copy link

@mihaic195 I have the same issue as you.I am creating an account and and when the reload happens i have an error with the email already exist because it creates with the same one. I hope i can get a workaround.

@mihaic195
Copy link

Probably the explanation with x.subdomain.domain.com was a bit too deep and confusing.
The basic principle is SSO: https://auth0.com/docs/sso/current

How can that work if you can't change the baseUrl? But I think this is a different problem than the refresh thing.

@andrei22b Please let me know if you find a workaround. For now I just left the login as it is - cypress navigates to login - completes form - submits form.

@andrei22b
Copy link

@mihaic195 i will let u know if i find something

@andrei22b
Copy link

@mihaic195 this 'hack' worked for me:
image

In my case visiting before any action the desired url helped me to not rerun the commands due to reload of the browser. Hope it helps you too !

@stuartbrussell-intuit
Copy link

stuartbrussell-intuit commented Jul 14, 2020

I'm curious why we need to deal with the baseUrl at all when going to a local file? One suggestion: if you get a url beginning with ".", assume it is a file and don't prepend the baseUrl. It seems like this issue is more about changing the baseUrl midstream, and less about visiting a file (even though the title and some of the discussion are about visiting a file).

Btw, it would be very helpful if the documentation for the visit command had a note emphasizing that the baseUrl is prepended even for a local file. That would have saved us some time trying to figure it out.

@stuartbrussell-intuit
Copy link

@jennifer-shehane Is it possible to re-open #4450 as a single-subject issue? The point is that opening a file should not require any consideration of the baseUrl, whether it is set or not. Most of the discussion here is about changing the baseUrl, which is really not relevant to opening a file. In other words, the title of this issue could be shortened to "allow a script to change the baseUrl while running" and it would match the discussion. Thanks in advance. It is good to see prompt activity in the project. :)

@cypress-bot cypress-bot bot added stage: proposal 💡 No work has been done of this issue and removed stage: needs investigating Someone from Cypress needs to look at this labels Aug 19, 2020
@emilyrohrbough
Copy link
Member

The current behavior appears to be working as expected. The baseUrl configuration is updating correctly for null and an empty string when updated via the test overrides and inline via the Cypress.config helper.

cypress.json

{
  "baseUrl": "https://example.cypress.io"
}

spec.js

it('visits base url', () => {
  cy.visit('/')
  cy.then(() => {
    	expect(Cypress.config(‘baseUrl)).to.eq(‘https://example.cypress.io')
  })
})

it('visits local file - test-override', { baseUrl: null }, () => {
  cy.then(() => {
    	expect(Cypress.config(‘baseUrl)).to.be.null
  })
  cy.visit(/public/index.html')
})

 it('resets baseUrl', () => {
    cy.then(() => {
      Cypress.config('baseUrl', ‘https://example.cypress.io')
       expect(Cypress.config('baseUrl')).to.eq(‘https://example.cypress.io')
   })
    cy.visit('/')
  })

  it('visits local file -  inline override', () => {
    cy.then(() => {
      expect(Cypress.config('baseUrl')).to.eq(‘https://example.cypress.io')
      Cypress.config('baseUrl', null)
      expect(Cypress.config('baseUrl')).to.be.null
    })

    cy.visit('/public/index.htmll')
  })

In the example provided on the original issue summary, setting the baseUrl to a single space like Cypress.config(‘baseUrl’, ‘ ‘) is correctly updating the baseUrl value, however this is not a valid value for the baseUrl and window.location.origin is being prepended, which is why the unexpected behavior is being observed.

The baseUrl should be set to a fully quality url that is prefixed with either http:// or https://. Cypress should be throwing an error that this is an invalid configuration value. We will be making an update to add configuration validation to in-test configuration updates.

@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review stage: work in progress and removed stage: work in progress stage: needs review The PR code is done & tested, needs review labels Oct 21, 2021
@cypress-bot cypress-bot bot added stage: needs review The PR code is done & tested, needs review stage: work in progress and removed stage: work in progress stage: needs review The PR code is done & tested, needs review labels Nov 2, 2021
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Nov 9, 2021

The code for this is done in cypress-io/cypress#18589, but has yet to be released.
We'll update this issue and reference the changelog when it's released.

@cypress-bot cypress-bot bot added stage: pending release and removed stage: needs review The PR code is done & tested, needs review labels Nov 9, 2021
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Nov 10, 2021

Released in 9.0.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v9.0.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Nov 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: enhancement Requested enhancement of existing feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.