How to check if specific action made a request using playwright? - javascript

It's my first time using Playwright and I just can't figure out how to check if a request is made to the server. I want to press a button that sends request and and validate if it was successful or not. I am using chromium from Playwright and making tests with Mocha and Chai. This is my code:
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(url);
await page.click('text=Send');
// Validate if the request is send
await browser.close();
I may be trying to do it wrong, but I don't have much experience with Playwright, so any help will be appreciated.

You can use page.waitForRequest, using the urlOrPredicate parameter to verify that the request matches your expectation.

I'm not sure I have it clear. As I see it, you'd need to make the requests to the API. You can check it in the docs. For example, after clicking the button:
test('api', async({ request }) => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(url);
await page.click('text=Send');
// your api call(s)
const req = await request.YOUR_REQ_METHOD('https://THE_URL_NEEDED');
// your assertion(s)
expect(req.ok()).toBeTruthy();
});
I'd just add, and I'm not saying this is the case, always consider if you need the use of a browser for achieving your goal.

Related

I'm trying to use the search bar of youtube but it returns error

(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://youtube.com')
await page.waitForSelector("#search")
await page.type('#search', 'cheese')
await page.screenshot({path: 'youtube.png'});
console.log('done')
})();
I tried to run this to send me the search results of something but it returns "Uncaught Error Error: Evaluation failed: Error: Cannot focus non-HTMLElement" Any idea what I did wrong and need to fix? I saw a similar post but it didn't have an answer and I know I could just go straight to the page but I want to know how to use the search bar.

Javascript fetch requests are empty when starting a session

I have the following simple PHP page:
<?php
echo 'done';
When I send a Javascript fetch request to that URL, I can inspect the response in the browser's dev tools and see that it returns the string 'done'.
Here is the request:
const response = await fetch(url, {
credentials: 'include'
});
On the other hand, if I start a session, the response is blank:
<?php
session_start();
echo 'done';
In both cases, the request headers are exactly the same, the response headers are exactly the same and the HTTP code is 200. It also works correctly if I manually go to that URL in the browser. It only fails specifically with fetch requests.
Note, I have display_errors and display_startup_errors set to On and nothing is outputted to the browser and nothing is logged in the log file either.
This behavior is because of a bug with Chromium that the devs have decided they "WontFix" and have stopped answering comments.
In order to get it to work, you need to manually read response.text() or response.json():
const response = await fetch(url);
const text = await response.text();
Once you do that, the response body will show up in your dev tools. If not, it will appear as if the response was empty, even if it wasn't.
You can use async with Await
Asyn function getData(url){
const response = await fetch(url);
const data = await response.json();
Console.log(data).
}
You can change the .json() to text()

Request data from server when other response complete in JavaScript

I requesting the server(written in Node.js) using "fetch-api" function of javascript. I want to make multiple request to the server When the user clicks a button.
Is there such a way in JavaScript ?
When the server responds. Then the second request Send.
And when second response come.
Third request send and so on...
Please help me . Thanks in advance!
the fetch function returns a promise.
you need to await it like so:
await fetch('http://test.com/1');
await fetch('http://test.com/2');
await fetch('http://test.com/3');
you can also access the responses like so:
const res1 = await fetch('http://test.com/1');
const data1 = await res1.json();
if (data1.foo == '123') {
await fetch('http://test.com/2');
await fetch('http://test.com/3');
}

Sending A postMessage in puppeteer (Nodejs Library)

I know how to receive postMessages ,but I am looking to send a postMessage request to a site
Just a Format
const puppeteer = require('puppeteer');
const yargs = require('yargs');
let command = yargs.argv._[0];
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
function sendMessageToContentScriptByPostMessage(data)
{
window.postMessage({cmd: 'message', data: data}, '*');
}
await page.goto(command, {waitUntil: 'networkidle0'});
await browser.close();
})();
So the user can do this, node postmessage.js https://www.example.com
You can use page.evaluate to run things inside the browser. Then you can send a postMessage:
await page.evaluate((data) => {
window.postMessage({cmd: 'message', data: data}, '*');
}, data);
Two things to keep in mind:
the evaluate runs inside the browser, while all the other scripts are inside NodeJS (you can think of remote vs local code, local = NodeJS, remote = Chrome)
because of this, variables inside the evaluate are different than outside. You need to explicitly pass the data to evaluate to move it into the browser context.

How would puppeteer wait for all redirects

I have a puppeteer project which needs to submit a form and then wait for the next page. The problem is that to get to the next page, the site would make around 3-4 redirects and only then will start loading the actual content.
It seems Puppeteer is getting stuck somewhere in the middle.
How would I go around this?
This is my code:
await page.goto('<url>/Login.html', {'waitUntil': 'networkidle0', timeout: 60000});
await page.click(USERID_SLCT);
await page.keyboard.type(creds.userId);
await page.click(PWD_SLCT);
await page.keyboard.type(creds.pwd);
await page.click(LOGINBTN_SLCT);
await page.waitForNavigation({'waitUntil': 'networkidle0'});
await timeout(240000); // wait for the redirects to be finished
await page.waitForSelector(BTN_SLCT, {timeout: 240000}); // make sure the page is loaded <-- would fail here
await page.screenshot({path: './screenshots/mainpage.png'});
I have encountered a similar issue and solved it by waiting for a specific selector in the desired page.
await page.waitForSelector('#manage-trips', { visible: true, timeout: 0 });

Categories