Puppeteer file-chooser upload not working - file-upload

I try to upload a video on instagram using puppeteer with FileChooser:
const selectBtn = await page.$x("selector...")
const [fileChooser] = await Promise.all([
page.waitForFileChooser(),
selectBtn[0].click()
]);
await fileChooser.accept(["./myvid.mp4"]);
But it is not working, nothing happens.
Did anyone get that to work or an idea what could be wrong?

Following the document, it should be:
const [fileChooser] = await Promise.all([
page.waitForFileChooser(),
page.click('selector...'),
]);

Related

Can't copy a text to the clipboard on nextjs ubuntu ec2 instance. Getting "Error: Both xsel and fallback failed" this error message

I am hosting nextjs server instance on ubuntu ec2, and trying to copy a text into a textfield using selenium. When copying a text to the clipboard, i am using clipboardy package.
As seen below, I am using write method from clipboardy(I've tried writeSync method as well, but it did not work) to write a text to the clipboard, and it actually works find on local dev environment but not on ubuntu ec2 server (Keep getting this error message, "Error: Both xsel and fallback failed"). Can someone tell me how I can copy a text to the clipboard without getting an error message on nextjs ubuntu ec2 server? Thanks ahead.
const driver = seleniumSetup();
await driver.get("https://www.sssd.co.kr/host/authorLogin.do");
await driver.sleep(1000);
let resultElement = await driver.findElement(By.id("naver_id_login_anchor"));
await resultElement.click();
console.log("naver login button clicked");
await driver.sleep(3000);
const elem_id = await driver.findElement(By.id("id"));
await elem_id.click();
await driver.sleep(3000);
await clipboard.write(id);
console.log(await clipboard.read());
await driver.sleep(3000);
await elem_id.sendKeys(Key.META, "v");
await driver.sleep(3000);
const elem_pw = await driver.findElement(By.id("pw"));
await elem_pw.click();
await driver.sleep(3000);
await clipboard.write(pw);
console.log(await clipboard.read());
await driver.sleep(3000);
await elem_pw.sendKeys(Key.META, "v");
await driver.sleep(3000);
await driver.findElement(By.id("log.login")).click();
await driver.sleep(5000);
const cookie = await driver.manage().getCookie("sssd_host_JSESSIONID");
const sessionId = cookie.value;
console.log(sessionId);
await driver.close();
return sessionId;

Puppeteer - Login falied only at automation

I'm trying to do login at a web page but when I try to do it through Puppeteer it fails.
The code below should redirect with success to https://prenotami.esteri.it/UserArea but it fails and redirect to https://prenotami.esteri.it/Home/Login
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless:false, ignoreDefaultArgs: ['--enable-automation']});
const page = await browser.newPage();
await page.goto('https://prenotami.esteri.it/UserArea');
await page.evaluate(() => {
document.querySelector('#login-email').value = "****#gmail.com"
document.querySelector('#login-password').value = "pass***"
document.querySelector('button[type="submit"]').click()
})
})();
As it can be seen, I've tried to disable automation.I also tried to put some delay but I couldn't realize where exactly
SOLVED:
I've changed the code and it works now
const extra = require('puppeteer-extra');
const stealth = require('puppeteer-extra-plugin-stealth')
extra.use(stealth())
extra
.launch({
headless: false,
args: ['--no-sandbox']
})
.then(async browser => {
const page = await browser.newPage();
await page.goto('https://prenotami.esteri.it/');
page.setDefaultNavigationTimeout(30000)
await page.type("#login-email", "*****#gmail.com")
await page.type("#login-password", "*****pass")
await page.click('button[type="submit"]')
await page.waitForNavigation({ waitUntil: 'domcontentloaded' })
await page.goto("https://prenotami.esteri.it/Services/Booking/751")
await page.waitForNavigation({ waitUntil: 'domcontentloaded' })

page.goto (puppeteer) does not stop calling itself when opening the same url it is navigating to

I am trying to convert an html web page into a pdf file by using puppeteer. It is converting the html web page into pdf file but the problem is that, page.goto is not stopping after its job is done. When this happens, the terminal I run this localhost server from becomes a little unresponsive. I also deployed it on heroku but when I visit the url, the server responds me with error code 503 and it does not convert to pdf there.
let printPDF = async () => {
try {
const browser = await puppeteer.launch({ headless: true});
const page = await browser.newPage();
await page.goto('http://localhost:3000/preview')
await page.pdf({ format: 'A4' , path: `${__dirname}/contact.pdf`, printBackground: true});
await page.close();
await browser.close();
console.log("repeat") //logging to see its repetition
}
catch (error) {
await page.close();
await browser.close();
}
}
getReviewPage = ((req, res) => {
printPDF()
res.sendFile(`${__dirname}/form.html`)
})
app.route('/preview').get(getReviewPage);
Since printPDF is an async function returning Promise, you need to wait for it to finish, with then for example:
const getReviewPage = (req, res) => {
printPDF().then(() => res.sendFile(`${__dirname}/form.html`)
}

How do I split my Jest + Puppeteer tests in multiple files?

I am writing automated tests using Jest & Puppeteer for a Front-end application written in Vue.js
So far I managed to write a set of tests, but they all reside in the same file:
import puppeteer from 'puppeteer';
import faker from 'faker';
let page;
let browser;
const width = 860;
const height = 1080;
const homepage = 'http://localhost:8001/brt/';
const timeout = 1000 * 16;
beforeAll(async () => {
browser = await puppeteer.launch({
headless: false, // set to false if you want to see tests running live
slowMo: 30, // ms amount Puppeteer operations are slowed down by
args: [`--window-size=${width},${height}`],
});
page = await browser.newPage();
await page.setViewport({ width, height });
});
afterAll(() => {
browser.close();
});
describe('Homepage buttons', () => {
test('Gallery Button', async () => {
// navigate to the login view
await page.goto(homepage);
await page.waitFor(1000 * 0.5); // without this, the test gets stuck :(
await page.waitForSelector('[data-testid="navBarLoginBtn"]');
await page.click('[data-testid="navBarLoginBtn"]'),
await page.waitForSelector('[data-testid="navBarGalleryBtn"]');
await page.click('[data-testid="navBarGalleryBtn"]'),
// test: check if we got to the gallery view (by checking nr of tutorials)
await page.waitForSelector('.card-header');
const srcResultNumber = await page.$$eval('.card-header', (headers) => headers.length);
expect(srcResultNumber).toBeGreaterThan(1);
}, timeout);
});
describe('Register', () => {
const btnLoginToRegister = '#btn-login-to-register';
const btnRegister = '#btn-register';
const btnToLogin = '#btn-goto-login';
test('Register failed attempt: empty fields', async () => {
// navigate to the register form page via the login button
await page.goto(homepage);
await page.waitForSelector(navLoginBtn);
await page.click(navLoginBtn);
await page.waitForSelector(btnLoginToRegister);
await page.click(btnLoginToRegister);
// test; checking for error messages
await page.waitForSelector(btnRegister);
await page.click(btnRegister);
const errNumber = await page.$$eval('#errMessage', (err) => err.length);
expect(errNumber).toEqual(3);
}, timeout);
test('Register failed: invalid char count, email format', async () => {
// fill inputs
await page.waitForSelector('#userInput');
await page.type('#userInput', 'a');
await page.waitForSelector('#emailInput');
await page.type('#emailInput', 'a');
await page.waitForSelector('#emailInput');
await page.type('#passInput', 'a');
await page.waitForSelector(btnRegister);
await page.click(btnRegister);
// test: check if we 3 errors (one for each row), from the front end validations
const err = await page.$$eval('#errMessage', (errors) => errors.length);
expect(err).toEqual(3);
}, timeout);
test('Register: success', async () => {
await page.click('#userInput', { clickCount: 3 });
await page.type('#userInput', name1);
await page.click('#emailInput', { clickCount: 3 });
await page.type('#emailInput', email1);
await page.click('#passInput', { clickCount: 3 });
await page.type('#passInput', password1);
await page.waitForSelector(btnRegister);
await page.click(btnRegister);
// test: check if go to login link appeared
await page.waitForSelector(btnToLogin);
await page.click(btnToLogin);
// await Promise.all([
// page.click(btnToLogin),
// page.waitForNavigation(),
// ]);
}, timeout);
test('Register failed: email already taken', async () => {
// navigate back to the register form
await page.waitForSelector(btnLoginToRegister);
await page.click(btnLoginToRegister);
await page.click('#userInput');
await page.type('#userInput', name2);
await page.click('#emailInput');
await page.type('#emailInput', email1); // <- existing email
await page.click('#passInput');
await page.type('#passInput', password2);
await page.click(btnRegister);
const err = await page.$eval('#errMessage', (e) => e.innerHTML);
expect(err).toEqual('Email already taken');
}, timeout);
});
I would like to be able to have a single test file that does the beforeAll and afterAll stuff, and each test suite: HomepageButtons, Register, etc. to reside in it's own test file. How would I be able to achieve this?
I've tried splitting tets into:
testsUtils.js that would contain the beforeAll and afterAll hooks and code but it doesn't guarantee that it runs when it needs: the beforeAll code to fire before all other test files and the afterAll code to fire after all the test files finished.
Sorry, I'd rather comment on your question, but I don't have reputation for that. Anyway, I think that you are looking for something like a "global beforeAll" and "global afterAll" hooks, right? Jest has it alread. It's called "globalSetup" and "globalTeardown".
Take a look at globalSetup. Excerpt:
This option allows the use of a custom global setup module which
exports an async function that is triggered once before all test
suites.
The Global Teardown one goes the same.
I think you'll have a headache trying to get a reference to the page or browser in globalSetup/globalTeardown and I confess that I never try this. Maybe the answer for that problem (if you have it) is on this page, under "Custom example without jest-puppeteer preset section.
Also there is a repo that tries to facilitate Jest + Puppeteer integration. Maybe you find it util: repo.
Good luck. :)

passport-jwt, not throing error, but not authenticating. wont even console.log

I am trying to authenticate using passport-jwt, express etc.
I currently am not getting authenticated, but most troubling is that I cant seem to console.log inside the function... nothing happens.
Here is the full passport.js
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../models/user');
const config = require('../config/database');
module.exports = function(passport) {
let opts = {};
opts.jwtFromRequest = ExtractJwt.fromHeader();
opts.secretOrKey = config.secret;
console.log(opts); // THIS SHOW PRIORE TO THE EXPRESS LISTEN MSG!
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
console.log(jwt_payload); // THIS DOESNT EVER SHOW!
User.getUserById(jwt_payload._id, (err, user) => {
if (err) {
return done(err, false);
}
if (user) {
return done(null, user);
} else {
return done(null, false);
// or create a new account
}
});
}));
}
the users.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
const config = require('../config/database');
const User = require('../models/user');
...code removed for brevity...
router.get('/profile', passport.authenticate('jwt', {session:false}), (req,res,next) => {
res.json({user: req.user});
});
module.exports = router;
Any ideas on how I can 'see' my payload so I can find whats going on?
Im using postman to hit 'http://localhost:3000/users/profile'
passing headers "authentication" and the token "JWT my-token..."
THx - I realize this is a bit of an odd request...The tutorial I was following, indicates I should be able to see the payload, even if i am not authenticated...
So Im kinda stuck with no idea where to turn.
UGH - this is the second time I've continued to plug away at something after I asked, only to hit upon a solution. apperantly the version Im am using is newer than the examples and ExtractJwt.fromHeader() should be .fromAuthHeaderWithScheme("jwt"). It is frustrating that it did not error, and did not progress enough to log, however - NOW I get my console log, and can see my payload... I hope this helps someone else. (I am frustrated with the pace and changes made to js libs, that destroy backwards compatibility, and do not clearly document a path, I understand kinda why it happens, but it makes learning and troubleshooting very frustrating)