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

Puppeteer - I.getCurrentUrl() returns last URL rather than current url #963

Closed
awshanks opened this issue Feb 25, 2018 · 10 comments
Closed

Comments

@awshanks
Copy link
Contributor

awshanks commented Feb 25, 2018

What are you trying to achieve?

What do you get instead?

Provide console output if related. Use --verbose mode for more details.

Open Github @sample --
 open browser and navigate to github.com
 • I am on page "https://github.com/awshanks"
 • I click "codecept_training_material"
 • I get current url 
https://github.com/awshanks

Provide test source code if related

Scenario('open browser and navigate to github.com', (I) => {
I.amOnPage('https://github.com/awshanks');
I.click('codecept_training_material');
I.getCurrentUrl().then(function (result) {
    console.log(result);
});
});

Details

  • CodeceptJS version: 1.1.5 (puppeteer 1.1.0)
  • NodeJS Version: 8.9.4
  • Operating System: MacOS
  • Protractor || WebDriverIO || Nightmare version (if related)
  • Configuration file:
# paste suite config here
@reubenmiller
Copy link
Collaborator

The I.getCurrentUrl Function does not exist on the Puppeteer helper. Are you using a custom helper? If so then it might be a bug with puppeteer and not codeceptjs.

But could you please elaborate and fill out the issue template in full so we can address the problem more easily.

@awshanks
Copy link
Contributor Author

Yes, I just added the function to the helper in the codecept node_module folder (saw the pull request for it) (as puppeteer custom helpers do not work right now).

I added the code above.

From https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions -
Bare in mind that if click() triggers a navigation event and there's a separate page.waitForNavigation() promise to be resolved, you may end up with a race condition that yields unexpected results. The correct pattern for click and wait for navigation is the following:
const [response] = await Promise.all([ page.waitForNavigation(waitOptions), page.click(selector, clickOptions), ]);

@reubenmiller
Copy link
Collaborator

@awshanks There are few things that are not clear to me.

  1. What do you mean that custom Puppeteer helpers do not work? You should be able to create a custom helper for any of the existing helpers. If you have a problem with the config then maybe I can help with that.

  2. For clicks that cause a navigation action, you need to wait for the navigation manually. There is a comment about this in puppeteer error "Cannot find context with specified id undefined" #914. We can't use the const [response] = await Promise.all([ page.waitForNavigation(waitOptions), page.click(selector, clickOptions), ]); by default because it will not work on elements that don't trigger a navigation action. However you could use the new retry feature introduced by @DavertMik in v1.1.5, so your test would look like:

Scenario('open browser and navigate to github.com', (I) => {
  I.amOnPage('https://github.com/awshanks');
  I.click('codecept_training_material');
  I.retry(3).seeInCurrentUrl('codecept_training_material');
});

@awshanks
Copy link
Contributor Author

Okay, thanks for the workaround. Glad to have it documented here for reference.

@awshanks
Copy link
Contributor Author

For the Puppeteer custom helper, I have the following function (works for selenium, nightmare etc, only addition is the page)

getCurrentURL() { var browser = this.helpers['Puppeteer'].browser; return browser.page.url(); }
Is this not correct?

@reubenmiller
Copy link
Collaborator

No the Puppeteer api is a little different to WebDriverIO etc.

The .url() function is actually on the Page object and not the Browser. Though in the helper we keep track of the current page in the .page property.

So an example custom Helper function would look like this.

async getCurrentUrl() {
  const helper = this.helpers['Puppeteer'];
  return helper.page.url();
}

@reubenmiller
Copy link
Collaborator

Here is the full example of a custom helper for sake of completeness.

'use strict';

let Helper = codecept_helper;

class MyCustomHelper extends Helper {
  async getCurrentUrl() {
    const helper = this.helpers['Puppeteer'];
    return helper.page.url();
  }
}

module.exports = MyCustomHelper;

@awshanks
Copy link
Contributor Author

Ah, I see, maybe an example in the puppeteer documentation would help others?

Again thanks for clarifying.

@reubenmiller
Copy link
Collaborator

@awshanks Not a problem I have just submitted a PR with a comment about how to access it from a custom Helper (like the example in the WebDriverIO). It will take a little bit before it is available from the doc website.

@awshanks
Copy link
Contributor Author

awshanks commented Mar 3, 2018

Okay, I think I've narrowed down the issue I was having and it seems that if a website use hash routing the page.url doesn't update after a click that directs to another page.

The I.click works fine and goes to the page and I see the url in the verbose output.

If I go to the page with I.amOnPage('/#/page') the route will change (and with show:true on I can see the correct page), but codecept doesn't know that the page has changed and the amOnPage will fails after it retries and I always just have the baseUrl that I defined in the config. (related to #945). Maybe a solution is for me not to use hashHistory.push('URL_HERE') and instead use . Sharing my observation for awareness. puppeteer/puppeteer#257

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants