I'm trying to do some tests with playwright. I use Azure B2C for the login service. I have followed the authentication documentation on official website: Playwright auth documentation
I have created a global-setup
// global-setup.ts
import { chromium, FullConfig } from '#playwright/test';
async function globalSetup(config?: FullConfig) {
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://myapp.it/it');
await page.click('text=Prosegui');
await page.waitForSelector('input[id="email"]');
await page.fill('input[id="email"]', 'usertest1#myapp.it');
await page.waitForSelector('text=Password');
await page.fill('text=Password', 'mypassword');
await page.click('text=Accesso');
// Save signed-in state to 'storageState.json'.
await page.context().storageState({ path: 'storageState.json' });
await browser.close();
}
export default globalSetup;
and I have defined the config in this way:
// playwright.config.ts
import { PlaywrightTestConfig } from '#playwright/test';
const config: PlaywrightTestConfig = {
globalSetup: require.resolve('./global-setup'),
// Use the default browser options, but override the
// headless mode.globalSetup: require.resolve('./global-setup'),
use: {
headless: false,
video: 'retain-on-failure',
viewport: { width: 1280, height: 720 },
baseURL: 'https://myapp.it/it/',
storageState: 'storageState.json',
//bypassCSP: true,
},
};
export default config;
Now, I have multiple files for multiple tests. If I debug global-setup function it works correctly, it do the login correctly but If I run other tests, the context of new browser doesn't add cookies stored in storageState.json and I'm not logged in.
import { test } from '#playwright/test';
//onboarding.spec.ts
test('onboarding', async ({ baseURL, page, context }) => {
await page.goto(baseURL);
await page.waitForSelector('text=Dashboard');
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
// await page.goto(`${baseURL}get-folder/details/**`);
await page.waitForNavigation({ url: 'get-folder/details/**' });
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
await page.getByRole('button', { name: 'arrow_forward_ios' }).click();
await page.getByText('Conferma').click();
// Use a glob URL pattern. Note no await.
await page.waitForResponse('/services/api/identity/tutorial/**');
});
If I run this test I can't proceed it because I'm not logged in and I'm unauthorized. I can't understand why cookies are not present in the context of new browser. What could be a solution?
Related
I am trying to perform a delete function on my nextjs app using mongoose, I was able a successfully achieve POST, GET method but still find it difficult to achieve the delete operation.
My POST method inside in API folder:
export default async function addUser(req, res) {
const data = req.body
await connectDB()
const myDocument = await userModel.create(data)
res.json({ myDocument })
}
Here is how I called it from my frontend:
async function Login(e) {
e.preventDefault()
const userObject = {
user_name: userName,
password: password
}
const response = await fetch('/api/add', {
method: 'POST',
body: JSON.stringify(userObject),
headers: {
'Content-Type': 'application/json'
}
})
const data = await response.json()
console.log(data)
}
I was able to read it using this method and parse the data through props and map through:
export const getServerSideProps = async () => {
await connectDB()
const myDocument = await userModel.find()
return {
props: {
myDocument: JSON.parse(JSON.stringify(myDocument))
}
}
}
How do perform the DELETE method?
I tried this:
export default async function Remove(req, res) {
await connectDB()
await userModel.deleteOne({_id: req.params.id}, function (err) {
if (err) {
console.log(err)
}
res.send("Deleted")
})
}
which is normally what will work using my node and express, But is not working here.
Here is the frontend function I tried:
function Delete(_id) {
fetch(`/api/remove/${_id}`)
.then(() => {
window.location.reload()
})
}
But it's not working.
So after a long study, I was able to come up with a solution.
I created a dynamic route in my "API" folder called "[id].js" and wrote the following code:
export default async (req, res) => {
const {query: {id}} = req
await connectDB()
const deletedUser = await userModel.findByIdAndDelete(id)
if (!deletedUser) return res.status(404).json({msg: "does not exist"})
return res.status(200).json()}
I edited my front-end to be:
async function Delete(_id) {
await fetch(`/api/${_id}`, {
method: 'DELETE'
}).then(() => {
//Do something here
})
}
I'm completely new to using RTK Query, I created the app before but without the authentication and everything worked, now I want to add the authentication using Auth0 but I can't access any file I add getTokenSilently()
PS. getTokenSilently is the {token}
thanks for help
export const myApi = createApi({
reducerPath: "points",
baseQuery: fetchBaseQuery({
baseUrl: "/",
prepareHeaders: (headers, { getState }) => {
const token = getState()
if (token) {
headers.Authorization = `Bearer ${token}`
}
return headers
},
}),
endpoints: builder => ({
getPoints: builder.query({
query: () => `/`,
}),
}),
})
export const { useGetPointsQuery } = myApi
What I ended up doing was to store the token in my state and then added this to App:
useEffect(() => {
(async () => {
try {
const token = await getAccessTokenSilently({})
dispatch(setToken(token))
} catch (e) {
console.error(e);
}
})()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [getAccessTokenSilently])
There is a little more logic to know if you have not yet authenticated so that you can render a pending authentication state, but this was enough to get me going.
I am using Axios with the proxy option I want to check bad proxy so I decide to set timeout to my GET request.
here is code:
let res= await axios.get(`http://somedomain.com`,
{
timeout:1500,
proxy: {
host: proxyList[indexOfProxy].host,
port: proxyList[indexOfProxy].port,
auth: {
username: '',
password: ''
},
}
}
).catch(err => {
console.log(`proxy ${indexOfProxy} not working.`);
});
but actually timeout did not work, it spends a long time to go to catch block .
Use axios.create()
const axios = require('axios').default;
const instance = axios.create({
baseURL: 'https://wainot.trade',
timeout: 5000,
});
async function run() {
try {
let res = await instance.get()
} catch (error) {
console.log('no')
}
}
run()
I have a NodeJS API which has an end-point who is responsible for receive some HTML from Quill Text Editor and then generate a .PDF file with this HTML content, but my downloaded .PDF file is always blank.
Here is my API end-point:
server.post('/exportarDocumento', checkDocumento, (req, res) => {
const documento = req.body.documento;
try {
gerarPDF(documento)
.then(pdf => {
console.log('PDF GERADO', pdf); // the output is a Buffer
res.set({ 'Content-Type': 'application/pdf', 'Content-Length': pdf.length });
res.send(pdf);
});
} catch (e) {
console.log('erro: ', e);
}
finally {
// do stuff
}});
gerarPDF() function:
async function gerarPDF(documento) {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setContent(documento, { waitUntil: 'networkidle0' });
const pdfBuffer = await page.pdf({ format: 'A4' });
await browser.close();
return pdfBuffer; };
And my axios call in ReactJS to the endpoint:
await axios.post('http://localhost:3000/exportarDocumento', { documento: this.props.text })
.then(response => {
const blob = new Blob([response.data], { type: 'application/pdf' });
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'Documento.pdf';
link.click();
});
The .PDF file is being downloaded, but is always blank. Does anyone know what I'm doing wrong?
I have a page with a button. When I click that button, it opens a PDF in a new tab.
How can I download the PDF as a file with puppeteer?
Maybe I can write a file with the buffer from the new tab. But I am not sure how.
A simple solution is to use the fetch api to execute the GET request. This way you can read the response, pass it to your backend and save it to disk.
Use this sample code as reference:
import fs from 'fs';
async function downloadImage(page: any, url: string, fullpath: string) {
const data = await page.evaluate(
// tslint:disable-next-line no-shadowed-variable
async ({ url }) => {
function readAsBinaryStringAsync(blob) {
return new Promise((resolve, reject) => {
const fr = new FileReader();
fr.readAsBinaryString(blob);
fr.onload = () => {
resolve(fr.result);
};
});
}
const r = await fetch(url, {
credentials: 'include',
headers: {
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp, */*;q=0.8',
'cache-control': 'no-cache',
pragma: 'no-cache',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-site',
'upgrade-insecure-requests': '1'
},
referrerPolicy: 'no-referrer-when-downgrade',
body: null,
method: 'GET',
mode: 'cors'
});
return await readAsBinaryStringAsync(await r.blob());
},
{ url }
);
fs.writeFileSync(fullpath, data, { encoding: 'binary' });
}
Use puppeteer-extra node module.
Puppeteer-extra
const puppeteer = require('puppeteer-extra');
...
...
puppeteer.use(require('puppeteer-extra-plugin-user-preferences')({userPrefs: {
download: {
prompt_for_download: false,
open_pdf_in_system_reader: true
},
plugins: {
always_open_pdf_externally: true // this should do the trick
}
}}))
const browser = await puppeteer.launch();
browser.on('targetcreated', async (target) => {
console.log('targetcreated');
if (target.type() !== 'page') {
return;
}
try {
const pageList = await browser.pages();
pageList.forEach((page) => {
page._client.send('Page.setDownloadBehavior', {
behavior: 'allow',
downloadPath: './pdfDownloaded/',
});
});
} catch (e) {
console.log("targetcreated", e);
}
});
...
...
But when i set the always_open_pdf_externally: true chrome crashes.
try if it works for you, and please post back the answer if you found any