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
Related
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)
})
})
I am trying to add an external script to my React Native app. The script is not available as an NPM package, so a tag is required.
The script requires me to attach a function to the window object. That function is triggered when the script loads. window.onExampleScriptReady = () => {}
I added polyfills for the window/document.
This code works perfectly in a web browser, but yields nothing on iOS. Not even any errors.
const script = document.createElement("script")
script.src = "https://my-example-script.js"
script.async = true
document.body.appendChild(script)
My solution does not require dynamic/runtime tag creation, so I'm open to solutions similar to adding a script tag in the index.html file. (which I don't believe React Native has)
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.
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.
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>