Puppeteer identifier string variable won't parse; Unsure why - javascript

I'm trying to have a string be used inside a puppeteer string, it won't work for some reason.
Specifically with this code
await page.waitForSelector('div[class = "sh-dlr__list-result"')
When i try to parse in a variable
let identified1 = 'div[class = "sh-dlr__list-result"'
so making
await page.waitForSelector(identified1)
It won't work. This is really limiting, is there a way around this issue?
This is the expanded code
https://jsfiddle.net/hewlbern/6p7kdozt/10/
Run it in your computer, jsfiddle unsure if I can run it from there.
I believe it is creating a cors error now - very weird! Why would using a variable create a cors error : /
Thanks!

The reason is because you're declaring identified inside the page.evaluate(). So, when you do the following it's already out of scope.
if (currentPage < pagesToScrape) {
console.log(identified1);
await Promise.all([
await page.click(buttonSelector),
await page.waitForSelector(identified),
]);
}
You did log the identified1 but you're using identified for the selector.
You'll have to pass the identifier2 to the pageFunction like so:
let newProducts = await page.evaluate(({ identifier2 }) => {
// ...
},{ identifier2 });
See here some examples:

Related

VSCode Extension Using executeDocumentSymbolProvider API

I am writing a VSCode extension and want to use the executeDocumentSymbolProvider API to get the list of functions of a file.
I mainly have 2 problems with how to use executeDocumentSymbolProvider:
How to correctly use executeDocumentSymbolProvider
How to resolve the returned Promise
How to correctly use executeDocumentSymbolProvider
Below are the links I referenced to call executeDocumentSymbolProvider:
https://code.visualstudio.com/api/references/commands
https://code.visualstudio.com/api/extension-guides/command
https://www.reddit.com/r/vscode/comments/oxnhna/get_all_symbols_of_the_current_document_in_vscode/
How can I implement my own code outline layout in vscode?
And this is how I call the API:
var active = vscode.window.activeTextEditor;
let symbols = await vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider',active.document.uri);
Although this does return a Promise, I can't help but wonder if this is the correct way to invoke it because from the VSCode API doc it looks like I should invoke it like let symbols = await vscode.commands.executeCommand<vscode.DocumentSymbol[]>('vscode.executeDocumentSymbolProvider',active.document.uri). However I keep getting an error that says there should be an argument in the [].
How to resolve the returned Promise
The following picture is the returned Promise.
I have tried the following methods to resolve it but I still get Promise instead of symbols array as the return value.
async function(){
var active = vscode.window.activeTextEditor;
let symbols = await vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider',active.document.uri);
}
var active = vscode.window.activeTextEditor;
vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider',active.document.uri).then((symbols) => {
if(symbols !== undefined){
console.log(symbols);
}
});
async function getFunctionList(textEditor){
var active = vscode.window.activeTextEditor;
return await new Promise((resolve, reject) => {
setTimeout(function(){
resolve(vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider',active.document.uri));
}, 1000);
});
}
Please let me know if you have used executeDocumentSymbolProvider before. Thank you!
Be sure to install the C/C++ Extension Pack by Microsoft on VSCode for getting symbols from a c file. Otherwise, VSCode won't be able to find the symbols.

CSVtoJSON returns UnhandledPromiseRejectionWarning: ReferenceError: JavaScript

I am trying to convert CSV from a CSV file to JSON.
I have the following code
(async() => {
csvToJson().fromStream(request.get("https://raw.githubusercontent.com/dsfsi/covid19za/master/data/covid19za_provincial_cumulative_timeline_confirmed.csv"))
.then(source => {
let latest_provinces_confirmed = source;
});
console.log(latest_provinces_confirmed)
...
and when I run it, I get
UnhandledPromiseRejectionWarning: ReferenceError: latest_provinces_confirmed is not defined
How can I get the result of the CSVtoJSON into a variable to use later
Thanks in advance
The variable 'lastest_provinces_confirmed' is declared inside the anonymous function so you cannot access it outside that function. Thats why console.logging variable doesn't work.
You can try to pass that variable outside of that function by returning it OR you can forward declare that variable outside those functions to be able to access it.
Something like this might work:
let latest_provinces_confirmed = csvToJson().fromStream(request.get("https://raw.githubusercontent.com/dsfsi/covid19za/master/data/covid19za_provincial_cumulative_timeline_confirmed.csv"))
.then(source => {
return source;
});
Remember to take account that you are working with async functions so you have to make sure that function csvToJson() has run before using 'latest_provinces_confirmed'. You can check use of "await" in order to do that!
You are doing a simple and a beginner level mistake. The scope of "let" is only inside the block. Change your code as below and it should work.
(async() => {
let latest_provinces_confirmed;
csvToJson().fromStream(request.get("https://raw.githubusercontent.com/dsfsi/covid19za/master/data/covid19za_provincial_cumulative_timeline_confirmed.csv"))
.then(source => {
latest_provinces_confirmed = source;
console.log(latest_provinces_confirmed)
....
});

How to get a collection of elements with playwright?

How to get all images on the page with playwright?
I'm able to get only one (ElementHandle) with following code, but not a collection.
const { chromium } = require("playwright");
class Parser {
async parse(url) {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(url);
await page.waitFor("img");
// TODO: get somehow collection of elements
return await page.$("img");
}
}
module.exports = Parser;
Somewhere in another module far far away:
const Parser = require("./path/to/dir/Parser.js");
const parser = new Parser();
parser
.parse(body.url)
.then(elemHandle => {
// here I get only one ElementHandle object, but suppose to get an array or collection
})
.catch(err => {
throw new Error(err);
});
Node v.12.16.1
I have already found the answer. Need to use page.$$(selector) instead of page.$(selector) to grab like document.querySelectorAll(selector).
As mentioned in the accepted answer, you can use await page.$$(selector).
Here is a link to the page.$$ official documentation
You can also use the following code.
const result = await page.evaluate(selector => document.querySelectorAll(selector) , selector);
Here is a link to the page.evaluate official documentation
for playwright use: await page.$$(selector);
There is another way to work with a list of elements you can read from the documentation. And I like it much more
https://playwright.dev/docs/locators#lists
So you just select using the page.locator and after that, you can interact with each element using for loop or selected the needed element using .nth()
For counting, when trying to avoid the use of await page.$$(selector);, another alternative is to directly use LocatorAssertion:
await expect(locator).toHaveCount(n);
Link to official documentation
Locator seems to be the current way forward. page.$$(img) is discouraged.
Instead use:
const imageList = await page.locator('img);
For count:
const imageList = await page.locator('img');
console.log('images: ', await imageList.count());
More information on https://playwright.dev/docs/locators

Can't get metadata selector text

This is a duplicate question to
node js puppeteer metadata
At the time of writing this question I don't have enough reputation to comment on the question.
I am writing some test scripts for a project and I want to test some seo metadata tags.
I check my selector in the chrome dev tools and it works fine.
document.querySelectorAll("head > meta[name='description']")[0].content;
and I receive the data no problem
but when I try to get it to work inside my testing script I can't seem to get a hold of the selector.
describe('guest jobs page', function () {
const {expect} = require('chai');
let page;
before(async function () {
page = await browser.newPage();
await page.goto('https://page');
});
after(async function () {
await page.close();
})
it('should have the correct page title', async function () {
expect(await page.title()).to.eql('page - Jobs');
});
it('should have the correct page description', async function () {
const DESCRIPTION_SELECTOR = "head > meta[name='description']";
await console.log( await page.evaluate((DESCRIPTION_SELECTOR) => document.querySelectorAll(DESCRIPTION_SELECTOR)));
expect(await page.$eval(DESCRIPTION_SELECTOR, element => element.textContent)).to.eql('page description content');
//this fails as no content is returned
//AssertionError: expected '' to deeply equal 'page description content'
});
});
any help would be appreciated, I don't know how to attach this question to the previous one without commenting so if someone could enlighten me about that I would also be very grateful. Thanks.
I believe console.log will be empty because DESCRIPTION_SELECTOR is undefined inside of page.evaluate.
In order to use a variable from the main script inside of page.evaluate one must explicitly pass it into the evaluating function:
await page.evaluate(DESCRIPTION_SELECTOR => document.querySelectorAll(DESCRIPTION_SELECTOR), DESCRIPTION_SELECTOR);
This is because page.evaluate operates in a kind of a sandbox and only has access to functions and variables declared at the web page opened by puppeteer (the so called "page context"). Since that page has no DESCRIPTION_SELECTOR, we must pass it in arguments of the page.evaluate, after the function to be evaluated. See also: documentation
As for page.$eval, it returns empty string because there is no textContent in meta tag, you need to use just content:
page.$eval(DESCRIPTION_SELECTOR, element => element.content)

TestCafe - How to check if a web element exists or does not exist without failing the test?

I'm trying to write a script that needs to adapt it's workflow behavior depending on whether a particular browser object found by CSS selector exists or does not exist.
I do not want to use a document.getElementByID method as this is not technically a CSS selector, and our entire enterprise is standardized on CSS selector so anything that walks the DOM other then a CSS selector won't make it past our code review process anyway.
var thing = await things.thingSelector(thingName);
if (await t.expect(thing.exists).notOk()) {
await t.click(things.OpenThing(thingName));
} else {
return false;
}
return true;
Where thingSelector is:
const thingSelector = name =>
Selector('p.thing-header-title span')
.withText(name)
.parent('div.thing');
Where OpenThing is:
const OpenThing = name =>
thingSelector(name)
.find('a.thing-footer-item')
.withText('Open');
I need to be able to continue execution if the object is not there and I'm checking that it exists, or if the object is there and I'm checking that it does not exist, and also the cases where the object is not there and it does not exist and the object is not there and I'm checking that it does not exist.
In all cases I still need to proceed with the workflow.
I've tried both sides of the logic coin:
if (!await t.expect(thing.exists).ok())
And
if (await t.expect(thing.exists).notOk())
If one of the above doesn't fail in one scenario it will fail in the other, and the other one will fail in the scenario that the first one didn't fail. I need something that will give me the logic, but not ever fail the script execution and still allow me to return either True or False depending on if the object is present or not present.
Thank you in advance for helping me to solve this problem, and also to learn and grow in my Javascript skills!
You can check the async exists property in the if condition in the following way:
if(await things.thingSelector(thingName).exists) {
// do something
}
You can use the following assertions to test existence and non-existence elements:
test('Test existence and non-existence elements', async t => {
await t
.expect(Selector('#existing-element').exists)
.expect(Selector('#non-existing-element').exists).notOk()
});
How to check if an element exists:
test('Element with id "element" exists', async t => {
await t.expect(Selector('#element').exists).ok(); });
How to check if an element does NOT exist:
test('Element with id "element" shouldn\'t exist', async t => {
await t.expect(Selector('#element').exists).notOk(); });
Check out the official documentation.
this is working for me, you can give it a try
async veriryCreativeIconButtonNotExists(){
await t.expect(this.exportButton.exists).ok()
await t.expect(this.columnPickerIcon.exists).ok()
await t.expect(this.filterColumnIcon.exists).ok()
if (await t.expect(this.columnPickerIcon.exists).ok()){
await t.expect(this.creavtiveIconButton.exists).ok()
await t.click(this.creavtiveIconButton)
await t.expect(this.creativeImage.exists).ok()
await t.click(this.creativeImage)
} else {
return false;
}
return true;

Categories

Resources