In order to go to an URL relative to the current domain name in Javascript, use window.location.origin
like this:
window.location.href = window.location.origin + "/myurl"
In order to go to an URL relative to the current domain name in Javascript, use window.location.origin
like this:
window.location.href = window.location.origin + "/myurl"
This template allows you to build your own TamperMonkey scripts that react on keypresses on a specific page.
This script shows an alert message when you press Alt+Q.
// ==UserScript== // @name TamperMonkey keypress example // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match https://techoverflow.net/* // @grant none // ==/UserScript== (function() { 'use strict'; function onAltQ() { alert("Alt Q pressed!"); } function onKeydown(evt) { // Use https://keycode.info/ to get keys if (evt.altKey && evt.keyCode == 81) { onAltQ(); } } document.addEventListener('keydown', onKeydown, true); })();
To emulate a keypress to the Page up
key in Puppeteer, use
await page.keyboard.press("PageUp");
To emulate a keypress to the Page down
key in Puppeteer, use
await page.keyboard.press("PageDown");
You are trying to compile your Angular 9.x application, but you see an error message like
app/my-component/my-component.component.ts:24:4 - error TS2554: Expected 2 arguments, but got 1. 24 @ViewChild(MyOtherComponent) myOtherComponent: MyOtherComponent; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../node_modules/@angular/core/core.d.ts:7888:47 7888 (selector: Type<any> | Function | string, opts: { ~~~~~~~ 7889 read?: any; ~~~~~~~~~~~~~~~~~~~ 7890 static: boolean; ~~~~~~~~~~~~~~~~~~~~~~~~ 7891 }): any; ~~~~~ An argument for 'opts' was not provided.
Find this line in your code at the location specified in the error message:
@ViewChild(MyOtherComponent) myOtherComponent: MyOtherComponent;
and add
{static: false}
as second argument to the @ViewChild()
declaration:
@ViewChild(MyOtherComponent, {static: false}) myOtherComponent: MyOtherComponent;
In most cases, you want to use static: false
. See this post on StackOverflow for details on when to use static: true
as opposed to static: false
.
You can remove all event listeners from a DOM element in Javascript by replacing the element with a deep clone of itself. elem.cloneNode(...)
will not clone the event listeners of the source element.
elem.replaceWith(elem.cloneNode(true));
Full example:
var elem = document.getElementById('mybutton'); elem.replaceWith(elem.cloneNode(true));
Source for the original (partial) suggestion on StackOverflow: @Felix Kling
Install argparse using
npm i --save argparse
Optional argument:
const ArgumentParser = require('argparse').ArgumentParser; const parser = new ArgumentParser({}); parser.addArgument(['-u', '--url'], {help: "The URL to use"}); const args = parser.parseArgs(); // Example usage console.log(args.url) // null if no such argument
If you want to make an argument mandatory, use required: true
:
const ArgumentParser = require('argparse').ArgumentParser; const parser = new ArgumentParser({}); parser.addArgument(['-u', '--url'], {help: "The URL to use", required: true}); const args = parser.parseArgs(); // Example usage console.log(args.url)
In case the user does not provide the argument, it will print
usage: CLI.js [-h] -u URL CLI.js: error: Argument "-u/--url" is required
This positional argument will always be required:
const ArgumentParser = require('argparse').ArgumentParser; const parser = new ArgumentParser({}); parser.addArgument(['url'], {help: "The URL to use"}); const args = parser.parseArgs(); // Example usage console.log(args.url)
When you try to run your puppetteer application, e.g. under docker, you see this error message:
Note: Unless you are running in a Docker or similar container, first consider running the application as non-root-user!
You have to pass the --no-sandbox
option to puppeteer.launch()
:
const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox'] });
We recommend to use this slightly more complex solution to pass it only if the process is being run as root
:
/** * Return true if the current process is run by the root user * https://techoverflow.net/2019/11/07/how-to-check-if-nodejs-is-run-by-root/ */ function isCurrentUserRoot() { return process.getuid() == 0; // UID 0 is always root } const browser = await puppeteer.launch({ headless: true, args: isCurrentUserRoot() ? ['--no-sandbox'] : undefined });
This ensures Chromium is run in the most secure mode possible with the current user.
Use this function to determine if the current NodeJS process is being run by the root
user:
function isCurrentUserRoot() { return process.getuid() == 0; // UID 0 is always root }
Usage example:
if(isCurrentUserRoot()) { // TODO Your code for root user goes here } else { // TODO Your code for NON-root user goes here! }
This works since the UID of the root
user is always 0
on Linux/Unix systems.
Note: You don’t need to
const process = require("process");
since the process
object is automatically imported in any NodeJS environment
You can use process.env.NODE_ENV
to check the value of the NODE_ENV
environment variable in Node.JS:
if(process.env.NODE_ENV == "development") { // TODO your code goes here }
or
if(process.env.NODE_ENV == "production") { // TODO your code goes here }
Note that by default NODE_ENV
is undefined
so remember to handle that case appropriately.
This is the minimal Koa.JS application which I use as a template for new NodeJS webserver applications.
#!/usr/bin/env node const router = require('koa-router')(); const koaBody = require('koa-body'); const Koa = require('koa'); const app = new Koa(); app.use(koaBody()); router.get('/', async ctx => { ctx.body = "Hello world"; }); app.use(router.routes()); if (!module.parent) app.listen(3000);
Install the requirements using
npm i --save koa koa-router koa-body
and run using
node index.js
assuming you have saved our code from above in index.js
.
Now (with the node index.js
command still running) go to http://localhost:3000 . You should see Hello world
there. Now it’s your turn to continue on your endeavour to develop the world’s greatest webservers 🙂
In NodeJS applications you often see code like
if (!module.parent) { app.listen(3000); }
This means: Run app.listen(3000)
only if you are running the file
Suppose this code is in index.js
. In this case, the code will only be executed if you run index.js
directly (i.e. using node index.js
) and not if index.js
is require
d from another file (by require('./index.js');
).
If index.js
is required from another Javascript module (i.e. file), module.parent
will be set to that module.
To emulate a keypress to the Enter
key in Puppeteer, use
await page.keyboard.press("Enter");
The E
needs to be uppercase for this to work!
To emulate the user typing something on the keyboard, use
await page.keyboard.type("the text");
This will type the text extremely fast with virtually no delay between the characters.
In order to simulate the finite typing speed of real users, use
await page.keyboard.type("the text", {delay: 100});
instead. The delay betwen characters in this example is 100 Milliseconds, i.e. the emulated user types 10 characters per second.
In order to emulate a tab
key press in Puppeteer, use
await page.keyboard.press("Tab");
Full example:
// Minimal puppeteer example const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({defaultViewport: {width: 1920, height: 1080}}); const page = await browser.newPage(); await page.goto('https://techoverflow.net', {waitUntil: 'domcontentloaded'}); // Press tab 10 times (effectively scrolls down on techoverflow.net) for (let i = 0; i < 10; i++) { await page.keyboard.press("Tab"); } // Screenshot to verify result await page.screenshot({path: 'screenshot.png'}); // Cleanup await browser.close(); })();
You want to emulate a tab key
press using
await page.keyboard.press("tab");
but you get an error message like
(node:30594) UnhandledPromiseRejectionWarning: Error: Unknown key: "tab" at assert (/home/uli/dev/myproject/node_modules/puppeteer/lib/helper.js:270:11) at Keyboard._keyDescriptionForString (/home/uli/dev/myproject/node_modules/puppeteer/lib/Input.js:96:5) at Keyboard.down (/home/uli/dev/myproject/node_modules/puppeteer/lib/Input.js:44:30) at Keyboard.<anonymous> (/home/uli/dev/myproject/node_modules/puppeteer/lib/helper.js:112:23) at Keyboard.press (/home/uli/dev/myproject/node_modules/puppeteer/lib/Input.js:178:16) at Keyboard.<anonymous> (/home/uli/dev/myproject/node_modules/puppeteer/lib/helper.js:112:23) at /home/uli/dev/myproject/test.js:8:23 at processTicksAndRejections (internal/process/task_queues.js:85:5) (node:30594) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2) (node:30594) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
You need to use Tab
, not tab
! The T
needs to be uppercase!
Use
await page.keyboard.press("Tab");
Full example:
// Minimal puppeteer example const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({defaultViewport: {width: 1920, height: 1080}}); const page = await browser.newPage(); await page.goto('https://techoverflow.net', {waitUntil: 'domcontentloaded'}); // Press tab 10 times (effectively scrolls down on techoverflow.net) for (let i = 0; i < 10; i++) { await page.keyboard.press("Tab"); } // Screenshot to verify result await page.screenshot({path: 'screenshot.png'}); // Cleanup await browser.close(); })();
Use this snippet to set the value of an HTML <input>
element in Puppeteer:
const newInputValue = "test 123"; await page.evaluate(val => document.querySelector('.search-form-input').value = val, newInputValue);amp
Remember to replace '.search-form-input'
by whatever CSS selector is suitable to select your <input>
. Examples include 'input[name="username"]'
or '.username > input'
.
Full example:
// Minimal puppeteer example const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://techoverflow.net', {waitUntil: 'domcontentloaded'}); // Set input value const newInputValue = "test 123"; await page.evaluate(val => document.querySelector('.search-form-input').value = val, newInputValue); // Screenshot to verify result await page.screenshot({path: 'screenshot.png'}); // Cleanup await browser.close(); })();
Note that this method will work for any simple <input>
, however it might not work for some heavily Javascripted inputs which you can find on some modern websites.
You can take a screenshot in Puppeteer using
await page.screenshot({path: 'screenshot.png'});
The path is relative to the current working directory.
Want to have a screenshot in a size different to 800×600? See How to set screenshot size in Puppeteer?
Full example:
// Minimal puppeteer example const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://techoverflow.net', {waitUntil: 'domcontentloaded'}); // Screenshot to verify result await page.screenshot({path: 'screenshot.png'}); // Cleanup await browser.close(); })();
The easiest way to sleep using async/await
in NodeJS is the sleep-promise package:
npm install --save sleep-promise
Using that package you can simply use await sleep(milliseconds)
syntax like this:
const sleep = require('sleep-promise'); // In any async function: await sleep(2000); // Wait 2000 ms
Note that this sleep()
variant is fully asynchronous, IO and other asynchronous operations will still be able to continue in the background – sleep()
will not block the NodeJS process.
Full example:
const sleep = require('sleep-promise'); (async () => { console.log("This prints immediately"); await sleep(2000); console.log("This prints 2 seconds later"); })();
Install the sleep-promise package:
npm install --save sleep-promise
then you can use
const sleep = require('sleep-promise'); // In any async function: await sleep(2000); // Wait 2000 ms
Full example:
const sleep = require('sleep-promise'); (async () => { console.log("This prints immediately"); await sleep(2000); console.log("This prints 2 seconds later"); })();
Using Python (pyppeteer)? Check out Pyppeteer minimal network response interception example
This example shows you how to intercept network responses in puppeteer.
Note: This intercepts the response, not the request! This means you can’t abort the request before it is actually sent to the server, but you can read the content of the response! See Minimal puppeteer request interception example for an example on how to intercept requests.
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Enable response interception page.on('response', async (response) => { console.info("URL", response.request().url()); console.info("Method", response.request().method()) console.info("Response headers", response.headers()) console.info("Request headers", response.request().headers()) // Use this to get the content as text const responseText = await response.text(); // ... or as buffer (for binary data) const responseBuffer = await response.buffer(); // ... or as JSON, if it's a JSON (else, this will throw!) const responseObj = await response.json(); }) await page.goto('https://techoverflow.net', {waitUntil: 'domcontentloaded'}); // Make a screenshot await page.screenshot({path: 'screenshot.png'}); await browser.close(); })();