Element inaccessible via Cypress Test Runner that is accessible via a regular browser - testing

Click here for image that compares the two different results returned for the same javascript command.
On the left is the image of the web page run inside Cypress Test Runner.
On the right is the image of the web page is a regular browser.
To produce the same result :
In standalone Chrome, load this url, open dev tools and then run the javascript command shown below.
document.querySelector('body#google-amp-body > amp-analytics:nth-child(3) > script')
Copy the following code into a spec file and run it inside Cypress Test Runner. Then open dev tools in the Test Runner window and run the same javascript command. You won't get anything back for this use case. See above screenshot to get a visual sense of what I mean.
If I try to perform cypress tests based on that element in Cypress I get nowhere because that element cannot be found inside Cypress.
If I access the same element via Python/Selenium code, it works fine.
describe('Gamespot Test', () => {
it('Tests for Video Page', () => {
const url = "https://gamespot.com/amp-videos/rainbow-six-extraction-final-preview/2300-6457072/"
cy.visit(url)
})
})

Related

Is it possible to disable custom/embedded screenshots in Cypress?

There is an option to disable screenshots in cypress.json but only for "screenshotOnRunFailure", when Cypress automatically takes a screenshot when there is a failure. Is it possible to disable custom screenshot "cy.screenshot()" passing parameter in run command like for video --config video=false. For example:
it('test screenshots', () => {
cy.get('someElement').click(); // user is redirected to another page
cy.screenshot();
cy.get('someElement').click();
cy.screenshot();
});
So, I need to run a command to include and ignore screenshots.

How to use puppeteer in vue.js

I'm trying to integrate puppeteer in a vue.js application to generate screenshots and pdf files.
I have write a function that use puppeteer to generate a screenshot, works perfectly.
export const MyScripts = {
getMiniature : async function(elementId, key) {
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Making a screenshot
}
}
When trying to integrate that function, it fails to load puppeteer.
The 'require' doesn't generate error, but when I call puppeteer.launch(), I got the following message:
TypeError: nodeFunction is undefined
I've read that puppeteer is not supposed to work with front-end application, so I hope I have not chosen the wrong direction.
So how can I make it work ?
If it is not possible, what can I use to generate screenshots or pdf ?
Thanks in advance
Puppeteer works with Node, it has nothing to do with Vue. Node.js is pretty much JavaScript running on a server and therefore separated from your frontend. Puppeteer uses a headless browser(and therefore your actualy system) to generate the screenshots and PDF files.
A client-side browser has no access to your filesystem and so therefore you can't use it in a frontend framework like Vue to generate screenshots and save them.
I don't know of any tools to generate screenshots of the current page that are not highly experimental but I am sure you could find some more information when deep-diving stackoverflow.
Disclaimer: This will not show you how to run puppeteer (chromium) on client side. This will only show you how to connect to a puppeteer instance running somewhere else.
Right now it's definitely possible on puppeteer version 1.9.0 (with a bit of headache).
Below I listed puppeteer web, client side pdf and image generation and external API.
1. Puppeteer web
It looks like you're trying to bundle puppeteer to use in a web application. Tip-of-tree Puppeteer is much more bundling-friendly and includes the browser field in its package.json that should help with bundling.
One thing you have to understand that the frontend does not have any access to the backend by any means other than REST/WS API. So either you have to use those API or build some api by yourself. You can build a simple express API and use that from the vue app. There are lots of resources and stackoverflow questions for that.
On that note, let's use the shiny puppeteer-web bundle. :)
Run Chrome and get browserWSEndpoint
You need to run chrome somewhere to have this. Probably on the server you are hosting the vue app. Assuming it's the chromium, you can use following code
chromium
--disable-background-networking \
--disable-background-timer-throttling \
--disable-breakpad \
--disable-client-side-phishing-detection \
--disable-default-apps \
--disable-dev-shm-usage \
--disable-extensions \
--disable-features=site-per-process \
--disable-hang-monitor \
--disable-popup-blocking \
--disable-prompt-on-repost \
--disable-sync \
--disable-translate \
--metrics-recording-only \
--no-first-run \
--safebrowsing-disable-auto-update \
--enable-automation \
--password-store=basic \
--use-mock-keychain \
--remote-debugging-port=0
This will result in something like,
DevTools listening on ws://127.0.0.1:57683/devtools/browser/foo
Make puppeteer browser version
Clone the puppeteer repo, install all modules and run the command to get specific web version you can embed on your UI.
git clone https://github.com/GoogleChrome/puppeteer
npm install
npm run bundle
You will see a utils/browser/puppeteer-web.js file. That's what you need to embed on your vue or web app.
Require puppeteer browser and connect to the endpoint
<script type="text/javascript" src="puppeteer-web.js"></script>
<script type="text/javascript">
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.connect({
browserWSEndpoint: theirBrowserWSEndpoint
// the exact same browser WS endpoint that just loaded this page,
// example, ws://127.0.0.1:57683/devtools/browser/foo
});
const page = await browser.newPage();
.. a whole bunch of operations to perform to data scraping, etc.
})()
</script>
PS: I will write an in depth article/answer about it soon with all kind of screenshots, stay tuned.
2. Capture current page as screenshot and pdf
You can use html2canvas to gather screenshot of current page. It's as simple as calling and using it. vue-resume uses this to generate final image. Useful if you are trying to capture the current page or any part of it.
Example usage,
var element = document.getElementById('capture');
html2canvas(element).then(canvas => {
document.body.appendChild(canvas) // do whatever want with the image data
});
Same with PDF generation. You can use html2pdf to do that.
var element = document.getElementById('capture');
html2pdf(element); // prompts the user to save the result
3. Screenshot Generation API
If you still need to generate screenshot, you can use available services. Here are some of them, (ps, the list might not be updated in future, and fail to work.)
Restpack: https://restpack.io/screenshot
Thum: https://www.thum.io
URL2PNG: https://www.url2png.com
url-to-pdf-api: https://github.com/alvarcarto/url-to-pdf-api

TestCafe: Uncaught ReferenceError: pagespeed is not defined

New to TestCafe.
Expected
Given .js below, expected behavior when running testcafe chrome this.js is to click on the header logo.
Actual
Uncaught ReferenceError: pagespeed is not defined (at the click below).
On our prod site, this error doesn't happen so most likely some configuration (possibly my version of Apache?) but I wanted to make sure there weren't any TestCafe specific issues. Followed installation using the standard docs (npm)
Thanks in advance!
import { Selector } from 'testcafe';
fixture `A set of examples that illustrate how to use Little Passports`
.page `https://xxx.xxdev.us/`;
test('My Company', async t => {
await t.
click('.header-logo');
});
I think I'll currently get around this by adding -e, but I'll keep this open just in case there's something else to consider...
By default, a test fails when there is a JavaScript error on page. The "-e (--skip-js-errors)" parameter allows running tests by skipping this JS error.
To check if there are any errors on your page, open your browser console. If there are any, you can either fix the errors at the application level (a preferable approach) or skip them during test run using the "-e" parameter.

Driving Nightwatch Tests through REPL

I currently have nightwatch.js setup using the vue automated setup. That template is located here.
https://github.com/vuejs-templates/webpack/tree/master/template/test/e2e
Is it possible to run nightwatch assertions through the command line in a REPL like fashion that is available in webdriver.io? Here is a reference to the webdriver feature https://twitter.com/webdriverio/status/806911722682544128
Update, we have moved to using Cypress.io It has made us pretty happy
You can use nightwatch-repl package available on NPM.
https://www.npmjs.com/package/nightwatch-repl
// nightwatch.conf.js
var repl = require('nightwatch-repl');
module.exports = (function (settings) {
repl.init(settings);
...
...
return settings;
})(require('./nightwatch.json'));
Once you run your tests and invoke browser.repl()
you should see the following in your console
Running: Login to dashboard
Type in a command (eg: browser.function()) or type "quit" to exit
repl>

Can I run Durandal's Tests Framework outside of PhantomJS?

The Durandal Test Framework runs Jasmine tests within PhantomJS.
Where I'm implementing this for the first time I'm getting a lot of errors, and reading through these on the command prompt is proving to be very tedious.
If I load up the spec.html file in my web browser, it tells me that no specs were found:
Yet PhantomJS is able to find the specs with no problem:
Is there a way I can configure these Jasmine tests to run through my web browser and not through (or as well as) PhantomJS?
I've set up a new index.html file and have replaced the var runTests = ... section with a simple require() call:
require(['../test/specs/system.spec.js']);
Durandal's system.spec.js file is loaded in the browser, but Jasmine is still stating that no specs were found.
Jasmine's tests weren't being run because I wasn't telling it to re-execute. The solution to this was to simply re-execute by calling this within the require callback:
require(['../test/specs/system.spec.js'], function() {
jasmine.getEnv().execute();
});
Note: A drawback of this is that the 'no specs found' bar is still present and the 'raise exceptions' control on the re-executed specs doesn't appear to function: