Puppeteer | Launching and running Chrome (not Chromium) on Visual Studio Code - visual-studio-code

I have tried my .js project with Chromium but it was very slow rather than Chrome's itself. So i decided running my program with Chrome on VS Code but this time VS Code created a file named launch.json and i couldn't achieve to bind index.js to launch.json.
Summary of my question, how can i run my script in Chrome on VS Code? What should i do to run launch.json and index.js together? I will leave my code blocks now.
launch.json:
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "url",
"webRoot": "${workspaceFolder}"
}
]
}
index.js:
const puppeteer = require('puppeteer')
const fs = require('fs/promises')
async function start() {
const browser = await puppeteer.launch({headless: false})
const page = await browser.newPage()
await page.waitForSelector('selector')
await browser.close()
}
start()
I didn't try anything essentially, because i don't know about solution. I researched on Google, Stackoverflow and Youtube too many times (2 days at least, maybe i can't find keyword because of my poor English) I described my problem as much as i can.
I must add, executablePath solution didn't work for me and
" crbug/1173575, non-JS module files deprecated. "
this error message appears on my debbugging console.
thx

Running program with Windows PowerShell is solution. The code that i execute:
const puppeteer = require('puppeteer')
const fs = require('fs/promises')
async function start() {
const browser = await puppeteer.launch( { headless: false,
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' })
const page = await browser.newPage()
await page.waitForSelector('selector')
await browser.close()
}
start()
So yes, executablePath is a solution, if you don't try that on VS Code.

Related

Debugging a Azure DevOps Task Extension (TypeScript)

I develop all our task extensions in PowerShell, now I start to translate my first extension into TypeScript. The extension is a small task which should run in build or release pipelines. The task should get deployed to a Azure DevOps Server 2020.1 (on prem).
Preparation
Tutorials
I follow the tutorial create a custom pipelines task and build a sample app with it
I clone the ansible task extension and checkout the programming style
System Setup
- Visual Studio Code
- Node (v14.15.4)
- TypeScript (Version 4.1.3)
- ts-node (v9.1.1)
- mocha (8.2.0)
- ts-mocha (8.0.0)
- azure-pipelines-task-lib (2.12.0)
Launch.json
{
"version": "0.2.0",
"configurations": [
{
"args": ["task/index.ts", "--Template", "Custom"],
"internalConsoleOptions": "openOnSessionStart",
"name": "Run TypeScript",
"request": "launch",
"runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"],
"skipFiles": ["<node_internals>/**"],
"type": "pwa-node"
}
]
}
Start up command:
node.exe --nolazy -r ts-node/register/transpile-only task/index.ts --Template Custom
The Issue
At runtime, when the tl.getInput function with required true get executed, the debugging stop immediately without any response (no error, no output).
App.ts:
import tl = require("azure-pipelines-task-lib/task");
export const App = {
Param: {
Test: "Here",
Template: tl.getInput("Template", true),
}
}
Index.ts (entry point):
import { App } from "./app";
function run() {
console.log("Hello");
console.log(App.Param.Test);
}
run();
Output (just nothing):
Index.ts (modified):
import { App } from "./app";
function run() {
console.log("Hello");
// console.log(App.Param.Test);
}
run();
Output (modified):
Hello
obviously it stops because the required variable Template get not passed to the application.
The Question
is there a way to debug an azure devops task extension?
is it possible to pass parameter and load them via tl.getInput?
is there a state of the art or a complete guideline how to develop azure devops task extension?
It is totally clear that running azure-pipelines-task-lib without a Azure DevOps environment run into issues. But I was hoping that it is possible to mockup the required pipeline variables and run this library locally. If using azure-pipelines-task-lib means that you have to deploy the extension and run it in a pipeline to test, it get kind of komplex to develop tasks with it, or?
Edit 1:
I found the deprecated repository about vsts-task-lib. In azure-pipelines-tasks/docs/debugging.md is manual to debug that library. The author of Debugging TypeScript Tasks in VS Code describe an example launch.json configuration and I modify it for my usecase:
{
"name": "Launch tar.gz",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/dist/task/index.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}/task",
"preLaunchTask": "tsc: build - tsconfig.json",
"runtimeExecutable": null,
"runtimeArgs": ["--nolazy"],
"env": {
"NODE_ENV": "development",
"INPUT_Separator": ";",
"BUILD_SOURCESDIRECTORY": "C:\\agents\\latest\\_work\\21\\s"
},
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/dist"]
}
I can confirm that it is possible to start up debugging and the tl.getInput("Separator") will return ;.
is there a way to debug an azure devops task extension?
Yes, According to the Step 1 in the article "Add a custom pipelines task extension", after installing all the required libraries and dependencies and adding all the required task implementation files, you can compile and run the task with PowerShell or other shells. By default, the task is run with debugging mode. See the example I share below.
is it possible to pass parameter and load them via tl.getInput?
Sure, you can pass the value of tl.getInput as an parameter. See the example I share below.
is there a state of the art or a complete guideline how to develop azure devops task extension?
Currently, the Microsoft Docs about DevOps extensions is the best guide for us to develop DevOps extensions.
Follow your case, I also test on my side, below are the main source code I use:
task.json
{
"$schema": "https://raw.githubusercontent.com/Microsoft/azure-pipelines-task-lib/master/tasks.schema.json",
"id": "dc7322d8-6c98-4be7-91c9-dcbf7f4df7dd",
"name": "buildAndReleaseTask",
"friendlyName": "Build and Release task",
"description": "Test create a Build and Release task.",
"helpMarkDown": "",
"category": "Utility",
"author": "Bright Ran",
"version": {
"Major": 0,
"Minor": 1,
"Patch": 0
},
"instanceNameFormat": "Echo $(UserName)",
"inputs": [
{
"name": "UserName",
"type": "string",
"label": "User name",
"defaultValue": "",
"required": true,
"helpMarkDown": "An user name"
}
],
"execution": {
"Node10": {
"target": "index.js"
}
}
}
App.ts (almost same as yours)
import tl = require("azure-pipelines-task-lib/task");
export const App = {
Param: {
Here: "Here",
UserName: tl.getInput("UserName", true),
}
}
index.ts (almost same as yours)
import { App } from "./App";
function run() {
console.log("Hello,", App.Param.UserName);
console.log("Look", App.Param.Here);
}
run();
Result to compile and run the task.
tsc
$env:INPUT_USERNAME="xxxx"
node index.js
From the result, you can see the two parameters can be passed normally.
With the help of Debugging TypeScript Tasks in VS Code I was able to do the following things:
read input parameter with tl.getInput from import tl = require("azure-pipelines-task-lib/task")
read environment variable with tl.getVariable from import tl = require("azure-pipelines-task-lib/task")
connect to Azure DevOps Server with new azdev.WebApi from import * as azdev from "azure-devops-node-api"
make a build api request with getBuildApi from import * as ba from "azure-devops-node-api/BuildApi"
run and debug application directly with TypeScript without JavaScript translation
launch.json
{
"name": "Run TypeScript",
"type": "pwa-node",
"request": "launch",
"internalConsoleOptions": "openOnSessionStart",
"stopOnEntry": false,
// path to your ts file
"args": ["index.ts"],
"cwd": "${workspaceRoot}/task",
"runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"],
"env": {
"NODE_ENV": "development",
// param (enter your input params here!)
"INPUT_WebhookUrl": "MyVariables",
"INPUT_Template": "Empty",
"INPUT_Json": "{\"text\":\"I am a test message\",\"attachments\":[{\"text\":\"And here’s an attachment!\"}]}",
"INPUT_Separator": ";",
// env
"AGENT_JOBSTATUS": "Succeeded",
"AGENT_NAME": "MyAgent",
"BUILD_BUILDID": "5",
"BUILD_BUILDNUMBER": "20210108.1",
"BUILD_REASON": "Scheduled",
"BUILD_REPOSITORY_NAME": "MyRepo",
"BUILD_SOURCEBRANCHNAME": "master",
"BUILD_SOURCEVERSION": "122a24f",
"BUILDCONFIGURATION": "Debug",
"BUILDPLATFORM": "Any CPU",
"SYSTEM_ACCESSTOKEN": "",
"SYSTEM_DEFINITIONNAME": "MyDefinitionName",
"SYSTEM_TEAMFOUNDATIONSERVERURI": "https://myurl.de/mycollection/",
"SYSTEM_TEAMPROJECT": "PSItraffic",
// debug
"DEBUG_PAT": "my debug pat"
},
"skipFiles": ["<node_internals>/**"]
}
Usecases
Read param & env: app.ts
import tl = require("azure-pipelines-task-lib/task");
export const App = {
// ------------------------------------------------------------ param
Param: {
WebhookUrl: tl.getDelimitedInput("WebhookUrl", "\n", true),
Template: tl.getInput("Template", true)
},
// ------------------------------------------------------------ env
Env: {
Agent: {
Jobstatus: getVariable("AGENT_JOBSTATUS"),
Name: getVariable("AGENT_NAME"),
},
...
System: {
AccessToken: getVariable("SYSTEM_ACCESSTOKEN"),
DefinitionName: getVariable("SYSTEM_DEFINITIONNAME"),
TeamFoundationServerUri: getVariable("SYSTEM_TEAMFOUNDATIONSERVERURI"),
TeamProject: getVariable("SYSTEM_TEAMPROJECT"),
},
// ------------------------------------------------------------ debug
Debug: {
Pat: getVariable("DEBUG_PAT"),
},
}
function getVariable(name: string): string {
// get variable
let v = tl.getVariable(name);
if (v === undefined) return "";
return v;
}
connect to azure devops server: rest.ts
import { App } from "./app";
import * as azdev from "azure-devops-node-api";
import * as ba from "azure-devops-node-api/BuildApi";
export class Rest {
static AuthHanlder: IRequestHandler = Rest.Auth();
static Connection: azdev.WebApi = new azdev.WebApi(App.Env.System.TeamFoundationServerUri, Rest.AuthHanlder);
static Auth(): IRequestHandler {
// auth
if (App.Env.System.AccessToken === "") return azdev.getPersonalAccessTokenHandler(App.Debug.Pat);
// no sure if this works on production
return azdev.getBearerHandler(App.Env.System.AccessToken);
}
}

Trying to write a vuepress plugin

(The doc on writing a plugin is pretty sparse...)
THE GOAL
Create a plugin to add headers to a page.
THE ATTEMPT
Created a plugin following guidelines and an example plugin (that presumably works...) to do something similar.
THE ISSUE
Plugin won't load.
config.js
plugins: [
[
'vuepress-plugin-headertags',
{ headerTags: ["<script src='https://cdn.jsdelivr.net/npm/netlify-identity-widget#1.5.2/build/netlify-identity-widget.min.js'></script>"]}
]
],
(the <script> tag is what I'm trying to insert, in this instance.
PLUGIN index.js
const { path } = require('path')
// was: const { path } = require('#vuepress/shared-utils')
// dunno. No documentation on this...
// got the current version from the 'default-theme' code
module.exports = (options) => ({
define () {
return {
headerTags: options.headerTags || []
}
},
enhanceAppFiles () {
return [path.resolve(__dirname, 'enhanceAppFile.js')]
},
globalUIComponents: ['HeaderTags']
})
PLUGIN INSTALLATION
I published it to npm as vuepress-plugin-headertags, and then installed it with:
yarn add -D vuepress-plugin-headertags
Here's the relevant package.json content:
{
"name": "vuepress-netlifycms",
"version": "0.0.0",
"scripts": {
"dev": "vuepress dev",
"build": "vuepress build",
"debug": "node --nolazy --inspect=9229 /home/rickb/.yarn/bin/vuepress build"
},
"devDependencies": {
"vuepress": "^0.14.8",
"vuepress-plugin-headertags": "^1.0.3"
},
"dependencies": {}
}
VUEPRESS INSTALLATION
I cloned the vuepress repo from git and did a yarn link, which makes it globally available. With that, I can trace it in the debugger via the 'debug' script.
TRACING
I've followed the VP source code in the debugger and get to resolvePathPackage() in moduleResolver.js. The incoming path is not correct:
/home/(...)/VuePress-NetlifyCMS/vuepress-plugin-headertags
It should be:
/home/(...)/VuePress-NetlifyCMS/node_modules/vuepress-plugin-headertags
At any rate, it doesn't resolve, even after the 'normalization' process.
MORE EYES
I need more eyes on this to help me figure it out. The project is already up on github as 'rickbsgu/VuePress-NetlifyCMS.git'. If you do an install, the plugin will be in the project directory under 'node_modules/vuepress-plugin-headertags'
Any thoughts appreciated
And it works, now. Two problems:
Version I was running/debugging was not the same as the version in package.json. There is the vuepress executable and the vuepress libraries the plugin requires. The library was always the older version at runtime.
I needed to change the path import in index.html from const { path } = require('path') to const { path } = require('#vuepress/shared-utils'). That's my doc issue - I don't see that documented anywhere.
Thanks #Sun Haoran for getting me to look in the right place.

Chrome in Mac is not starting in maximised state even after trying with '--start-fullscreen' in args

Need my chrome to start in maximised state every time my protractor suite initialises
Have already tried updating the chrome drive with webdriver-manager update. Still no go
I'm using this in my conf.js onPrepare function
capabilities: {
'browserName': 'chrome',
'platform': 'ANY',
'version': 'ANY',
'chromeOptions': {
args: ['--no-sandbox', '--test-type=browser', '--start-fullscreen',],
Right now I'm getting the message to press ^CommandF to exit full screen but the chrome is not actually in full screen
try switching '--start-fullscreen' with '--start-maximized'
Try with below chrome option
args: ['--kiosk']
Hope it helps you
I use these settings in my protractor-conf.js file, and it works on all type of OS : Windows, Mac, Linux etc.
onPrepare: function () {
browser.driver.executeScript(function () {
return {
width: window.screen.availWidth,
height: window.screen.availHeight
};
}).then(function (result) {
browser.driver.manage().window().setSize(result.width, result.height);
});
};

Accept alert in protractor is throwing `no such alert` error

I am writing an E2E test to accept alert.
It is a chrome dialog. Attaching pic for reference:
browser alert
Below is my code:
await browser.waitForAngularEnabled(false);
await browser.switchTo().alert().accept();
await browser.switchTo().defaultContent();
await browser.waitForAngularEnabled(true);
When trying to accept the alert, I get the below error
Failed: no such alert
(Session info: chrome=75.0.3770.27)
(Driver info: chromedriver=2.46.628411 (3324f4c8be9ff2f70a05a30ebc72ffb013e1a71e),platform=Mac OS X 10.13.6 x86_64)
Appreciate your suggestions on this.
First try to pass this to your capabilities in conf.js
capabilities: {
"browserName": "chrome",
"chromeOptions": {
"args": ["incognito", "--window-size=1920,1080", "disable-extensions", "start-maximized", "--test-type=browser"],
"prefs": {
"download": {
"prompt_for_download": false,
"directory_upgrade": true,
"default_directory": path.join(process.cwd(), "tmp/downloads")
}
}
}
},
I'm almost sure it'll help, if not take a look at my comment above^

Chrome Extension API v17: webRequest onErrorOccurred.addListener

I am attempting to set up a chrome extension similar to http://code.google.com/chrome/extensions/trunk/samples.html#webrequest except that it would us the onErrorOccurred listener instead to redirect to a specific known page when the get request fails for any reason.
manifest.json:
{
"name": "Custom Error",
"version": "0.1",
"description": "Redirect all navigation errors to specified location/file.",
"permissions": [
"webRequest",
"tabs",
"<all_urls>"
],
"background": {
"page": ["error_listener.html"]
}
}
error_listener.html:
<!doctype html>
<script>
chrome.webRequest.onErrorOccurred.addListener(
function onErrorOccurred(details) {
console.log('onBeforeRequest ', details.url);
return { redirectUrl: 'http://www.google.com' }
},
{urls: ["<all_urls>"]}
//{urls: ["http://*/*", "https://*/*"]}
);
//chrome.tabs.update(details.tabId, {url: "http://www.google.com", ['blocking']});
//alert("what?");
</script>
The extension loads without any errors indicated yet the browser tab is not redirected. I have tried this using both Chrome 16 and Chrome 17; when using Chrome 16, I did change "chrome.webRequest" to "chrome.experimental.webRequest" and added "experimental" to the permissions list.
So far it seems like the problem is that while the extension appears to be loaded when looking at chrome://extensions, the files are not actually loaded--when using Developer Tools, I don't see any reference to error_listener.html.
I have also tried running Chrome 17 with the following flags:
8611 25/01/12-11:22:05> google-chrome --restore-last-session
--debug-on-start --log-level=0 --enable-logging
--enable-extension-activity-logging --enable-extension-alerts
--debug-plugin-loading --debug-print | tee > log1.txt
Obviously, I am just kind of poking around in the dark with that command line. Anyone have any clue as to how to get this working? Thanks in advance for your help!
There is no webRequest.onErrorOccurred event. You may use webNavigation.onErrorOccurred. If you want to catch DNS errors and redirect to another url you may use the code:
<script>
chrome.webNavigation.onErrorOccurred.addListener(function(details)
{
if (details.frameId != 0) //ignore subframes. 0 is main frame
{ return; }
chrome.tabs.update(details.tabId, {url: "https://www.google.com/search?q=" + details.url});
});
</script>
In Chrome 16, you should be using:
"background_page": "background.html"
rather than
"background": {
"page": ["error_listener.html"]
}
This fixes the problem with the background page not loading. It looks like this may have changed in the trunk docs compared to the current docs, and I'm not sure which version of Chrome starts implementing the new manifest.json format.