BackstopJS icon indicating copy to clipboard operation
BackstopJS copied to clipboard

unable to login with puppeteer onBefore script

Open agazen opened this issue 6 years ago • 4 comments

Hi, I'm new in backstopjs and puppeteer and I'm trying to login to my app through the onBefore.json file but it doesn't seem to work correctly. It even doesn't perform.

{ "id": "backstop_default", "viewports": [
{ "label": "tablet", "width": 1024, "height": 768 } ], "onBeforeScript": "puppet/onBefore.js", "onReadyScript": "puppet/onReady.js", "scenarios": [ { "label": "BackstopJS Homepage", "cookiePath": "backstop_data/engine_scripts/cookies.json", "url": "myUrl", "referenceUrl": "", "readyEvent": "", "readySelector": "", "delay": 0, "hideSelectors": [], "removeSelectors": [], "hoverSelector": "", "clickSelector": "", "postInteractionWait": 0, "selectors": [], "selectorExpansion": true, "expect": 0, "misMatchThreshold": 0.1, "requireSameDimensions": true } ], "paths": { "bitmaps_reference": "backstop_data/bitmaps_reference", "bitmaps_test": "backstop_data/bitmaps_test", "engine_scripts": "backstop_data/engine_scripts", "html_report": "backstop_data/html_report", "ci_report": "backstop_data/ci_report" }, "report": [ "browser" ], "engine": "puppeteer", "engineOptions": { "args": [ "--no-sandbox" ] }, "asyncCaptureLimit": 5, "asyncCompareLimit": 50, "debug": true, "debugWindow": true }

Or maybe there is something wrong with my puppeteer script?

(async () => { const puppeteer = require('puppeteer'); const browser = await puppeteer.launch(); const page = await browser.newPage({ waitUntil: 'domcontentloaded' });

const loginEl = await page.$('#tbxLogin');
const passwordEl = await page.$('#tbxPassword');
const btnSubmitEl = await page.$('#btnLogin');       

loginEl.value = 'zzz';
passwordEl.value = 'yyy';
btnSubmitEl.click();

})();

Could you please help me?

agazen avatar Jun 21 '19 14:06 agazen

Best way to log in is to grab a valid set of cookies from your server, then modify the cookies.json file. Logging in manually is not really recommended.

Maybe this issue will help... https://github.com/garris/BackstopJS/issues/688

garris avatar Jun 22 '19 20:06 garris

Using cookies with backstop is very very very confusing. Is there a good tutorial on how to maintain a session throughout the backstop browsing process? Also, all of these examples tell you to "just export cookies" from your browser. Every browser I try has the cookies stored as a database. How do we export them? I've seen one site that gives you a python script and another that suggests a random tool from the internet... I have trust issues with these options. Where should we put them after we export them? Why wouldn't either Chromy or Puppetteer simply maintain their own set of cookies naturally instead of resetting the session after every scenario?

loopy3025 avatar Jul 31 '20 13:07 loopy3025

Wow, you sound really frustrated. Don't worry -- It's going to be ok!

Did you read the setting cookies section of the doc? https://github.com/garris/BackstopJS#setting-cookies

Please note -- you'll need this plugin to export cookies 👉 https://chrome.google.com/webstore/detail/cookie-inspector/jgbbilmfbammlbbhmmgaagdkbkepnijn?hl=en

Please try again using that plugin. It will export a JSON file -- you should store that with your test files and set the cookie path in your config to point to that file.

Hopefully this helps some. ☮️

garris avatar Jul 31 '20 15:07 garris

@loopy3025 @garris

After almost loosing my mind, I think I finally figured it out :) loadCookies.js file checks if the domain starts with a protocol in line 14: if (cookie.domain.startsWith('http://') || cookie.domain.startsWith('https://')) {

Which is weird, since a domain shouldn't and even the "export cookies" extension linked doesn't (rightfully so).

When that check fails, it simply assumes "https" without checking the "secure" flag from the cookie. So, in summery, nothing regarding cookies will ever work in BackstopJS if you're using http, which is very common when working locally.

I suggest something like this instead:

// MUNGE COOKIE DOMAIN
cookies = cookies.map(cookie => {
  if (cookie.domain.startsWith('http://') || cookie.domain.startsWith('https://')) {
    cookie.url = cookie.domain;
  } else {
    if (cookie.secure) {
      cookie.url = 'https://' + cookie.domain;
    } else {
      cookie.url = 'http://' + cookie.domain;
    }
  }
  delete cookie.domain;
  return cookie;
});

If plain http is not supported for cookies, I think that should be clear in the documentation. Thanks

tambourine-man avatar Apr 09 '24 04:04 tambourine-man