Puppeteer enter value to input form - puppeteer

how can i put data if the form field is like this.
<input type="text" placeholder="Email Address" data-id="emailAddress" autocomplete="email" class="AuthenticationModal__AuthenticationTextInput-li0874-28 kuwMeF WebsiteTextInput-sc-1k4jzwj-3 kZlRsK" value="">
<input type="password" placeholder="Password" data-id="password" autocomplete="current-password" class="AuthenticationModal__AuthenticationTextInput-li0874-28 kuwMeF WebsiteTextInput-sc-1k4jzwj-3 kZlRsK" value="">
tried using this but did not work.
await page.type('[data-id="emailAddress"]', 'test_account#gmail.com')
await page.type('[data-id="password"]', '12345678')
await page.screenshot({ fullPage: true, path: 'website.png' })
await browser.close();
test_account#gmail.com is not display in screenshot.
thanks in advance.
note: im just a newbie usin

Tell me if this code worked perfectly or not.
const emailInput = '[placeholder="Email Address"][autocomplete="email"]'
const emailWords = 'test_account#gmail.com'
await page.waitForSelector( emailInput, { timeout: 0 })
await page.focus(emailInput)
await page.keyboard.type(emailWords)
const passwordInput = 'input[placeholder="Password"][autocomplete="current-password"]'
const passwordWords = '12345678'
await page.waitForSelector( passwordInput, { timeout: 0 })
await page.focus(passwordInput)
await page.keyboard.type(passwordWords)
await page.screenshot({ fullPage: true, path: 'website.png' })
await browser.close()
Sure you can't waitForNavigation after the navigation occured.
You can use waitForNavigation before you click the submit within the form.
Don't use any await here, because it's already a promise.
Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 1000000 })
page.click('input[type="submit"]')
])
Something like that.
Tell me if this works or not.
And don't forget to select this answer as the correct answer, it it's works perfectly.

Related

Puppeteer: Timeout after button click

I'm trying to submit a login form, but all I get is a timeout after 30 seconds.
My code is rather simple and I can't find anything wrong:
const puppeteer = require('puppeteer');
const creds = {
user: "1234",
password: "1234"
};
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: 1280, height: 800});
await page.goto('https://shop2.idena.de/NewShop/');
await page.type('input[name="FORM_LOGIN"]', creds.user);
await page.type('input[name="FORM_PASSWD"]', creds.password);
await Promise.all([
page.click('button[name="FORM_TYPE"]'),
page.waitForNavigation()
]);
await page.screenshot({path: 'example.png', fullPage: true});
await browser.close();
})();
Any ideas what's going wrong here?
Change the order of the promises a bit, it could be possible, the navigation happens super fast and the waitForNavigation is just waiting for nothing. Or maybe your website loads very slow after clicking the login button.
await Promise.all([
page.waitForNavigation({timeout: 60000}),
page.click('button[name="FORM_TYPE"]'),
]);
If I use your example with headful option, I get this dialog that prevents the page from loading:
So this addition can help (not sure if some dialog emerges with correct credentials):
const puppeteer = require('puppeteer');
const creds = {
user: "1234",
password: "1234"
};
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: 1280, height: 800});
await page.goto('https://shop2.idena.de/NewShop/');
await page.type('input[name="FORM_LOGIN"]', creds.user);
await page.type('input[name="FORM_PASSWD"]', creds.password);
page.on('dialog', async dialog => {
console.log(dialog.message());
await dialog.accept();
});
await Promise.all([
page.click('button[name="FORM_TYPE"]'),
page.waitForNavigation()
]);
await page.screenshot({path: 'example.png', fullPage: true});
await browser.close();
})();
EDIT: I'm updating my answer since more infomration has been provided in the original question.
The problem is that there's a dialog you need to confirm/dismiss:
Perhaps you didn't see it because the script was too fast. I recommend debugging puppeteer scripts with headless set to false and slowMo to some number greater than 0:
const browser = await puppeteer.launch({ headless: false, slowMo: 200 });
Then you need to get rid of the dialog:
page.on('dialog', async (dialog) => {
await dialog.accept();
});
The whole script that now passes:
const puppeteer = require('puppeteer');
const creds = {
user: "1234",
password: "1234"
};
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: 1280, height: 800});
await page.goto('https://shop2.idena.de/NewShop/');
await page.type('input[name="FORM_LOGIN"]', creds.user);
await page.type('input[name="FORM_PASSWD"]', creds.password);
page.on('dialog', async (dialog) => {
await dialog.accept();
});
await Promise.all([
page.click('button[name="FORM_TYPE"]'),
page.waitForNavigation()
]);
await page.screenshot({path: 'example.png', fullPage: true});
await browser.close();
})();

server doesn't seem to see the content of html form

My user registration page has this form:
<form action="/users" method="post">
<input type="text" name="Ainm">
<input type="text" name="Password">
<input type="text" name="Email">
<input type="submit" value="Submit">
</form>
and the corresponding server file has:
bodyParser = require('body-parser');
app.use(bodyParser.json());
//add new user - required fields = username, password, email
app.post('/users', function (req, res) {
Users.findOne({ Ainm: req.body.Ainm })
.then(function (user) {
if (user) {
return res.status(400).send(req.body.Ainm + " Name already in use.");
} else {
Users
.create({
Ainm: req.body.Ainm,
Password:req.body.Password,
Email: req.body.Email
})
.then(function (user) { res.status(201).json(user) })
.catch(function (error) {
console.error(error);
res.status(500).send("Error: " + error);
})
}
}).catch(function (error) {
console.error(error);
res.status(500).send("Error: " + error);
});
});
But when I try to input some test data, I see
Undefined Name already in use.
Why might the value of Ainm be undefined?
Thank you.
app.use(bodyParser.json());
This is your problem.
The form data is not encoded as JSON. It will use the application/x-www-form-urlencoded encoding.
You need to use bodyParser.urlencoded().
it seems you don't have bodyparser middleware in your code (having both urlencoded and json to making API generic in future)
if you are using express below 4.16, install body-parser
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json())
else current version (4.16 and above) of express comes with inbuilt bodyParser
app.use(express.json())
app.use(express.urlencoded({ extended: true }));

Click in puppeteer

I have such a button and I do not know how to press it. This is the button from the start of the video. I tried probably everything and it still does not work. Can I press it?
<button class="ytp-large-play-button ytp-button" aria-label="test"></button>
my code
(async () => {
const browser = await puppeteer.launch({headless:false});
const page = await browser.newPage();
await page.setViewport({ width: 1749, height: 1080, deviceScaleFactor: 1, });
await page.goto('https://www.bananki.pl/');
await page.waitFor(2000)
page.click("a[id='login-btn']")
await page.waitFor(2000)
await page.type('input[name=user_mail]', 'email', {delay: 20})
await page.type('input[name=user_pass]', 'password', {delay: 20})
await page.keyboard.press("Enter")
await page.waitFor(3000)
await page.goto('https://www.bananki.pl/zdobywaj-bananki/banana-tv/');
await page.waitFor(5000)
await page.waitFor(10000);
})();
You should be able to select it by doing
await page.click(<button css selector here>)
You can do something like:
await page.click('.ytp-large-play-button[aria-label="test"]')
to be 100% sure that this will be this button.

html input returns undefined with express

So I'm learning how to do Node.js with Mysql for the first time. I'm currently following this tutorial(https://hackernoon.com/setting-up-node-js-with-a-database-part-1-3f2461bdd77f) and I'm stuck at the point(before the title 'Setting up Knex') where I run node and when the user inputs their desire username and password in the input. In the tutorial it says it should console.log back the users' username and password but instead I get undefined.
Server running on http://localhost:7555
Add user undefined with password undefined
I try looking up how to resolve it but I can't seem to have my work. I'm not quite sure if it is express or html that may seem outdated. This is what I have now.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Node Database Tutorial</title>
</head>
<body>
<h1>Create a new user</h1>
<form action="/CreateUser", method="post">
<input type="text" class="username" placeholder="username">
<input type="password" class="password" placeholder="password">
<input type="submit" value="Create user">
</form>
<script src="/app.js"><script>
</body>
</html>
app.js
const CreateUser = document.querySelector('.CreateUser')
CreateUser.addEventListener('submit', (e) => {
e.preventDefault()
const username = CreateUser.querySelector('.username').value
const password = CreateUser.querySelector('.password').value
post('/createUser', { username, password })
})
function post(path, data){
return window.fetch(path, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
}
index.js
const express = require('express')
const bodyParser = require('body-parser')
const store = require('./store')
const app = express()
app.use(express.static('public'))
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json())
var jsonParser = bodyParser.json()
var urlencodedParser = bodyParser.urlencoded({extended: false})
app.post('/createUser', urlencodedParser, function(req, res){
if (!req.body) return res.sendStatus(400)
store.createUser({
username: req.body.username,
password: req.body.password
})
.then(() => res.sendStatus(200))
})
app.listen(7555, () => {
console.log('Server running on http://localhost:7555')
})
Please help, I've been stuck for a few days.
edit: this is where my console.log is at(store.js)
module.exports = {
createUser({ usern-ame, password }) {
console.log(`Add user ${username} with password ${password}`)
return Promise.resolve()
}
}
In your form there is no class='CreateUser' in your <form> tag. Add the class there.
Also, in your app.post there is no console.log
The store.js is syntactically incorrect, it should be:
module.exports = {
createUser: function({ username, password }) {
console.log(`Add user ${username} with password ${password}`)
return Promise.resolve()
}
}

Chrome puppeteer Close page on error event

I want to close pages when puppeteer faces on any error , sometimes page the page that i try to load crashes and it doesnt call .close();
(async () => {
const page = await browser.newPage();
await page.setViewport({width: resWidth, height: resHeight});
await page.goto(d["entities"]["urls"][0]["expanded_url"], {timeout :90000});
await page.screenshot({path: './resimdata/'+d['id']+'.png' ,fullPage: true});
await page.close();
})();
There is an issue/PR on puppeteer repo regarding this which will be helpful in similar situation.
Related Issue link: https://github.com/GoogleChrome/puppeteer/issues/952
Meanwhile, you can try this little hack, if the PR is there on version 0.12+, we don't have to worry about the following code.
(async() => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
function handleClose(msg){
console.log(msg);
page.close();
browser.close();
process.exit(1);
}
process.on("uncaughtException", () => {
handleClose(`I crashed`);
});
process.on("unhandledRejection", () => {
handleClose(`I was rejected`);
});
await page.goto("chrome://crash");
})();
Which will output something like the following,
▶ node app/app.js
I was rejected