How do you enter text into a Flash TextArea from Puppeteer? - javascript

I am trying to automate login in a Flash object via Puppeteer. I have automated focusing on the Flash TextArea just by clicking, and that seems to work (the vertical blinking bar that indicates that you are typing appears). However, I have tried using page.keyboard.press, page.keyboard.up/page.keyboard.down, and page.keyboard.type, and none successfully enter text into the username or password field. Furthermore, I have set a piece of injected Javascript to console.log the key name of every keypress event on the Flash object, and it only fires when I am manually typing while focused on the Flash object. It does not log anything during my attempts to use Puppeteer keyboard inputs. My code is as follows:
const login = async (page) => {
await page.waitFor(20);
const username = process.env.SIGNIN_USERNAME;
await page.click(500,500); // Select the username field
await page.waitFor(20); // Allow the blinking bar to appear
await page.keyboard.type(username);
for(let char of username) {
await page.keyboard.press(char);
await page.waitFor(20); // So that it appears like a user is typing
}
for(let char of username){
await page.keyboard.down(char);
await page.waitFor(10);
await page.keyboard.up(char);
await page.waitFor(20);
}
await page.type("object",username); // The Flash object is the first object on the page
console.log(username) // The username is logged to the console and is defined
};
This code does not result in any text appearing in the Flash TextArea. However, the correct username is logged to the console.
Am I making a mistake, or is there some general way in Puppeteer or even just in browser Javascript to enter text into a Flash TextArea that I'm missing? Thanks.

Try using a more low-level function like keyboard.sendCharacter, which doesn't deal with all the weird event handling of keyboard.press.

Related

how do I assign specific json data for web automation?

I'm using puppeteer to do web automations. I'm automating the task to fill up a form. My script is set to open multiple browsers so as to automate filling the form alot faster. However I need each browser automation to use separate information. Here's the code below.
for(let i = 0; i<json.length; i++){
await page.type('#firstName', json[i].firstName);
await page.type('#lastName', json[i].lastName);
await page.type('#phone', json[i].phone);
await page.type('#address1', json[i].unitNumber);
await page.type('#address2', json[i].address1);
await page.type('#address3', json[i].address2); //not complusory(for sg region ONLY)
await page.type('#town', json[i].townCity);
await page.type('#county', json[i].stateProvince); //not complusory(for sg region ONLY)
await page.type('#postcodeLook', json[i].postalCode);
}
Here's my json (just a template but there would be lines of information in this format.)
firstName;lastName;phone;unitNumber;address1;address2;townCity;stateProvince;postalCode
There error Im facing is that when inputing the data into the form it actually fills in the whole list of information into one of the forms input section. What I mean is , e.g for firstName it will fill in firstName1, firstName2, firstName3 and so on depending on the number of data in the json. How would I fix this? Thank you in advance

Webscrape testing on a text field with jest-puppeteer

Okay everyone, got a bit of a doozy here. I am attempting to write a test using Jest and puppeteer for an email field. The problem is that I cannot seem to figure out how to get this test working. What I want to test is that if a user types in nothing into the email field, then an error message is displayed properly. I have attached photos of the CSS selector properties where you will find a customError: This cycles between true and false if valid inputs are in or not. I have also attached the HTML snippet where you will find the Id. I am a beginner at webscraping, JS, puppeteer, and Jest so I know this isn't ideal and I am sure there are many issues with my code. email text field image
CSS selector props close-up image
full view with devtools
I guess I cant embed images yet either so the links are provided!
test('empty field', async () => {
browser = await puppeteer.launch();
page = await browser.newPage();
await page.goto('https://platform.adcritter.com/')
await page.click('input[name=email]');
await page.type('input[name=email]', '') // no input
const doesItPass = await page.$$eval('input#if248af80-b989-11eb-8fad-f1ae53f1cff4',
validity => {expect({customError:true})}
)
browser.close()
}, 10000)
<input type="text" id="if248af80-b989-11eb-8fad-f1ae53f1cff4" name="email" placeholder="username#domain.com" class="euiFieldText euiFieldText--withIcon euiFieldText--fullWidth" tabindex="1" autocomplete="email" value="" aria-describedby="if248af80-b989-11eb-8fad-f1ae53f1cff4-error-0">

How to improve PuppeteerSharp code to set input value and click button

I have to use PuppeteerSharp to login to one web site.
The web page uses JavaScript to generate dynamic class, so each time when I tried to login, I can see different class name.
So using Puppeteer Recorder is useless, I can't use its code to login.
But I checked its HTML structure, I found it is rather simple: there is one submit form with 3 input fields, the first one is input field for User_Name,
the second input field for Password, the third is button to submit the form.
So nowadays, I can use the following code to login with a lot of keyboard typings. But my code was NOT a good one, as other keyboard actions will make it a mess.
But I can't find any good PuppeteerSharp code to do something like this:
Find all 3 input fields, then type the user name in the first one, type the password in the second one, and click on the third one.
Please advise!
_page = await _bookie_browser.NewPageAsync();
await _page.SetViewportAsync((new ViewPortOptions { Width = 1920, Height = 3938 }));
await _page.GoToAsync("https://www.webpage.com");
await _page.WaitForTimeoutAsync(2000);
await _page.FocusAsync("input");
await _page.Keyboard.TypeAsync("username");
await _page.WaitForTimeoutAsync(1000);
await _page.Keyboard.PressAsync("Tab");
await _page.WaitForTimeoutAsync(1000);
await _page.Keyboard.TypeAsync("password");
await _page.Keyboard.PressAsync("Tab");
await _page.WaitForTimeoutAsync(1000);
await _page.Keyboard.PressAsync("Enter");
await _page.WaitForTimeoutAsync(1000);

Image shows 1 thing, but queried data shows another when loading a website

I was trying to query a website: const url = "https://personal.vanguard.com/us/FixedIncomeHome" with the hope to automate some functionality within puppeteer.
I noticed if i create a screen shot: page.screenshot("preclick.png") it will show the page data with tabs. When i try to follow it up with a query, it seems to not return the second tab (denoted by the following selector: a[container="CD"]
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(url, {waitUntil: 'networkidle2'})
page.screenshot("start.png")
page.evaluate( () => {
document.querySelectorAll("a[container='CD']")[0].click()
})
///...
and i dont really know why this is the case. Ideally, i am trying to click CD and then click an empty search. I noticed that since session ids are tracked, I wanted to do this as a sort of E2E test in order to get the resulting table data.
I see that the Content of tab etc is dynamically loaded, so somehow there is an issue with the page being able to query.
I was attempting something else to see what would occur, waiting for the tag to appear, BUT it would just timeout after 30 seconds:
await page.waitForSelector("a[container='CD']").then( async resolve => {
page.execute( () => document.querySelector("a[container='CD']").click() );
});
I dont know why the screenshot shows the HTML, but when attempting to query for it from within execute it fails. It doesnt make sense to me why this occurs. Ideally, I want to click CD tab, then i want to click Search, then i want to loop through the 20 results in the table.
EDIT I was noticing that evaluate was not querying the component correctly because of an iframe. If i want to develop e2e testing though, i assumed there was a way to somehow get a reference to the button and click it, or simulate a click.*
You can get the iframe from a selector. As the iframe has the ID TWRIFrame, you can wait for that selector, then get the contentFrame from that element.
Once you have the frame, the frame class has almost the same functions as the page class, e.g. click.
Notice that, as that iframe is from other domain, with the --disable-features=site-per-process flag.
const browser = await puppeteer.launch({headless: false, args: ['--disable-features=site-per-process']});
const page = await browser.newPage();
await page.goto('https://personal.vanguard.com/us/FixedIncomeHome', {waitUntil: 'networkidle2'});
await page.screenshot("start.png");
await page.waitForSelector('#TWRIFrame');
const frameElement = await page.$('#TWRIFrame');
const frame = await frameElement.contentFrame();
await frame.click("a[container='CD']");

Entering data into multiple form inputs in Puppeteer

I'm trying to fill out a form in Puppeteer with an email and password, and then hit submit.
Each time the tests are run either the email or password isn't fully entered before the submit button is pressed. This is a cut-down version of what I'm doing:
await page.type(selectorSlackInputEmail, email);
await page.type(selectorSlackInputPassword, password);
await page.click(selectorSlackButtonSignIn);
I think it might be because the test isn't properly awaiting the completion of page.type and therefore focus switches to the next input or the submit button is pressed before each input field is complete.
How do I get around this problem?
I would expect your await directives to cover the issue you're seeing - my best guess is that because the type method simply...
sends keydown, keypress/input and keyup events [1]
... that maybe some listeners are taking a little while to execute their hooked functions between the sending of those events and the calling of the click method.
How about a workaround that explicitly checks that those selectors have the expected data before clicking submit?
await page.type(selectorSlackInputEmail, email);
await page.type(selectorSlackInputPassword, password);
await page.waitFor(() => {
return document.querySelector(selectorSlackInputEmail).value = email) &&
document.querySelector(selectorSlackInputPassword).value = password);
});
// And only *then*
await page.click(selectorSlackButtonSignIn);
After trying other methods (including await page.type and await page.focus followed by await page.keyboard.type) this is the only thing that works for me to fill multiple form fields:
await signInPage.evaluate(
(email, password) => {
document.querySelector('input#email').value = email;
document.querySelector('input#password').value = password;
},
email,
password
);
This doesn't satisfy my original use case though. I want to properly simulate a user typing into forms but this method circumvents that and directly inserts values into the fields.
I'd welcome a 'proper' solution to this problem.
I had the same problem in my code and decided to just use a delay with the click function.
await page.click('input[value="SUBMIT"]', {delay: 100});

Categories