Puppeteer file form issue - forms

Hi I can't accede to the input field. I have tried with id, class, name, title inserting a delay but without success.
import puppeteer from 'puppeteer';
//const puppeteer = require('puppeteer')
const preparePageForTests = async (page) => {
// Pass the User-Agent Test.
const userAgent = 'Mozilla/5.0 (X11; Linux x86_64)' +
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.39 Safari/537.36';
await page.setUserAgent(userAgent);
}
(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await preparePageForTests(page);
await page.goto('https://serviciosenlinea.bps.gub.uy/ServiciosEnLineaWeb/contenidosEmbebido?id=8782', {
waitUntil: "networkidle0", //domcontentloaded networkidle0
});
await page.screenshot({
path: 'images/skjdkjkfj.jpg'
});
await page.waitForSelector('[title=empresa]');
await page.typte('[title=empresa]', 'ssddsd');
await page.waitForSelector('#frmBasico:txtEmpresat');
await page.typte('#frmBasico:txtEmpresat', 'ssddsd');
await page.screenshot({
path: 'images/screenshot11.jpg'
});
await page.waitForSelector('.inputAlfanumerico');
await page.waitForSelector('#frmBasico:txtEmpresat');
await page.type('.inputAlfanumerico', 'Noseeee');
await page.type('#frmBasico:txtEmpresat', 'Noseeee');
await page.screenshot({
path: 'images/screenshot.jpg'
});
await page.focus('.frmBasico:txtDocumento');
await page.keyboard.type('342323243');
//await browser.close();
})();
I have tried with id, class, name, title inserting a delay but without success. I can't auto complete the inputs.
Any one know how to auto complete the inputs and submit in this case??
Thanks a lot :)

Related

How to wait until the Finder is visible for next code execution in Flutter integration test?

Information:
I have created a sample Flutter unit test to test the login screen where I have email & password as input field and a login button.
Requirement:
Need to test false cases and for that, I have written code as per the below steps.
Open main.dart
Filled the email & password field
onTap event is done on the login button. Over here API will be called and loader is displayed on the screen until API gets a success or failure response.
Need to check if failure dialog is displayed with a message.
Issue/Query:
Now when the API is calling I want to wait when the loader is visible until the loader is gone. So, as of now I just put a manual delay to execute the next code but I want to make it dynamic. So, let me know how we can put dynamic delay based on the loader visible?
Code:
void main() {
group('App Test', () {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('Login Fail Test', (WidgetTester tester) async {
await app.main();
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 2));
final emailField = find.byType(TextFormField).first;
final passwordField = find.byType(TextFormField).last;
final loginButton = find.byType(RaisedButton).first;
await tester.enterText(emailField, 'Test');
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 1));
await tester.enterText(passwordField, 'Test123');
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 1));
await tester.tap(loginButton);
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 3));
final dialog = find.byType(AlertDialog).first;
await tester.element(dialog);
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 1));
final dialogButton = find.byType(FlatButton).first;
await tester.tap(dialogButton);
await tester.pumpAndSettle();
await tester.pump(new Duration(seconds: 2));
});
}
I have a file called utils.dart for functionality like this. In this case I use the following function which will basically poll until the finder is valid
// utils.dart
Future<void> pumpUntilFound(
WidgetTester tester,
Finder finder, {
Duration timeout = const Duration(seconds: 10),
}) async {
bool timerDone = false;
final timer = Timer(timeout, () => timerDone = true);
while (timerDone != true) {
await tester.pump();
final found = tester.any(finder);
if (found) {
timerDone = true;
}
}
timer.cancel();
}
You can also make it throw an exception if it times out, but the error messages aren't helpful, so I usually follow it up with an expect
It would look like
// my_test.dart
final fab = find.byKey(const ValueKey('fab'));
await pumpUntilFound(widgetTester, fab);
expect(fab, findsOneWidget);
Try wrapping like this:
testWidgets('test',
(WidgetTester tester) async {
await tester.runAsync(() async {
// test code here
});
});
If you use:
await tester.pumpAndSettle();
And then:
final widget = find.byKey(Key('whatever'));
It will find dinamically

Displaying multiple Items in the list to an ftp server Flutter

I want to display multiple Items in the list and store it in the ftp server. So far I can only store the first index, now I want when the user decides to take multiple photos, they can be stored also on the ftp server. So may you please help how can I loop through photos file list and achieve this: Check my code below
final photos = <File>[];
Future<void> fileUpload() async {
FTPConnect ftpConnect = FTPConnect('xxxxxxxx',
user: 'xxxxxxxxx',
pass: 'xxxxxxxxx',
port: xx,
//isSecured: false,
debug: true);
try {
File fileToUpload = await File(photos.first.path);
await ftpConnect.connect();
await ftpConnect.changeDirectory('public_html');
await ftpConnect.changeDirectory('assets');
await ftpConnect.changeDirectory('images');
await ftpConnect.changeDirectory('app');
await ftpConnect.sizeFile('$photos');
await ftpConnect.rename('CAP4077791735949912884.jpg', 'laptop.jpg');
await ftpConnect.uploadFile(fileToUpload);
await ftpConnect.disconnect();
} catch (e) {
//error
await _log('Error: ${e.toString()}');
}
}
Try putting the code in the loop with the length of the list of photos.
final photos = <File>[];
for (File photo in photos) {
// your code to upload file to the FTP server
}
A loop will do the trick:
Future<void> fileUpload() async {
FTPConnect ftpConnect = FTPConnect('x.x.x',
user: 'x',
pass: 'x',
port: 0,
//isSecured: false,
debug: true);
try {
File fileToUpload = await File(photos.first.path);
await ftpConnect.connect();
await ftpConnect.changeDirectory('public_html');
await ftpConnect.changeDirectory('assets');
await ftpConnect.changeDirectory('images');
await ftpConnect.changeDirectory('app');
await ftpConnect.sizeFile('$photos');
await ftpConnect.rename('CAP4077791735949912884.jpg', 'laptop.jpg');
photos.forEach((element) async {
File _file = File(element.path);
await ftpConnect.uploadFile(_file);
});
await ftpConnect.disconnect();
} catch (e) {
//error
debugPrint(e.toString());
}
}

access document.documentElement from puppeteer

I can get access to the entire HTML for any URL by opening dev-tools and typing:
document.documentElement
I am trying to replicate the same behavior using puppeteer, however, the snippet below returns {}
const puppeteer = require('puppeteer'); // v 1.1.0
const iPhone = puppeteer.devices['Pixel 2 XL'];
async function start(canonical_url) {
const browserURL = 'http://127.0.0.1:9222';
const browser = await puppeteer.connect({browserURL});
const page = await browser.newPage();
await page.emulate(iPhone);
await page.goto(canonical_url, {
waitUntil: 'networkidle2',
});
const data = await page.evaluate(() => document.documentElement);
console.log(data);
}
returns:
{}
Any idea on what I could be doing wrong here?

In puppeteer how to wait for DOM element to load and then click

In puppeteer how to wait for DOM element to load and then click. I am trying access a simple page, hit the Start button and then a text field should appear, and I need to type in that text field.
Code given as below.
const puppeteer = require('puppeteer');
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://janus.conf.meetecho.com/videocalltest.html');
await page.click('#start', {waitUntil: 'domcontentloaded'});
//await sleep(5000);
await page.type('#username', 'austin');
await sleep(5000);
await browser.close();
})();
However if I put a sleep of 5 second (commented in above code), then I am able to type in text field.
I want to avoid giving sleep. Please suggest what's the work around.
You need to wait for the element to be visible because the element is present in the DOM, but not visible.
Here is the script that works:
(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://janus.conf.meetecho.com/videocalltest.html');
await page.click('#start');
await page.waitForSelector('#username', { visible: true });
await page.type('#username', 'austin');
// await browser.close(); // commented it just to make sure that text is typed in the input before close browser.
})();
You can use ;page.waitForSelector(selector[, options]):
await page.waitForSelector('#username', {visible: true})
//Errors
await page.waitForSelector('#username', {visible: true})
.then(()=>{
console.log('success');
})
.catch((err)=>{
console.log(err);
}

Async and await tasks take too much time

I need to call all APIs and store a local database before login. I used the sqflite plugin. can't add background running, that's why I used await.
1st running storeRegister() after process completed then running storeEquipmentReg likewise.
button onPressed():
await HelperDatabase1().storeRegister(_url, tokens);
await HelperDatabase1().storeEquipmentReg(_url, tokens);
await HelperDatabase1().storeGetUserPreference(_url, tokens);
await HelperDatabase1().storeDefRegisterCat(_url, tokens);
await HelperDatabase1().storeDefCatMaster(_url, tokens);
await HelperDatabase1().storeDefCatRelation(_url, tokens);
await HelperDatabase1().storeWoDescription(_url, tokens);
await HelperDatabase1().storeAssetAssembly(_url, tokens);
await HelperDatabase1().storeCategoryDefect(_url, tokens);
await HelperDatabase1().storeWorkSource(_url, tokens);
await HelperDatabase1().storeWorkTypes(_url, tokens);
await HelperDatabase1().storePriorities(_url, tokens);
await HelperDatabase1().storeSignIn(1);
await HelperSync().insert(_url, tokens);
await Helper().insert(token);
Navigator.pop(context);
Navigator.of(context).pushNamedAndRemoveUntil('/listView', (Route<dynamic> route) => false);
example storeCategoryDefect method:(All other code same)
storeCategoryDefect(String url, String token) async {
var db = await db1;
Batch batch = db.batch();
final response = await http.get(
'$url/nativeapi/v1.0/CategoryDefect',
headers: {'Authorization': 'Bearer $token'},
);
final jsonResponse = json.decode(response.body);
CategoryDefect model = CategoryDefect.fromJson(jsonResponse);
int length = model.data.length;
for (int i = 0; i < length; i++) {
var data = DataCategoryDefect(
i: model.data[i].i,
d: model.data[i].d,
);
batch.insert(
'CategoryDefectTable',
data.toMap(),
);
}
await batch.commit();
}
If you don't need to execute them in a specific order, you can execute them simultaneously like:
await Future.wait([
HelperDatabase1().storeRegister(_url, tokens),
HelperDatabase1().storeEquipmentReg(_url, tokens),
HelperDatabase1().storeGetUserPreference(_url, tokens),
HelperDatabase1().storeDefRegisterCat(_url, tokens),
HelperDatabase1().storeDefCatMaster(_url, tokens),
HelperDatabase1().storeDefCatRelation(_url, tokens),
HelperDatabase1().storeWoDescription(_url, tokens),
HelperDatabase1().storeAssetAssembly(_url, tokens),
HelperDatabase1().storeCategoryDefect(_url, tokens),
HelperDatabase1().storeWorkSource(_url, tokens),
HelperDatabase1().storeWorkTypes(_url, tokens),
HelperDatabase1().storePriorities(_url, tokens),
HelperDatabase1().storeSignIn(1),
HelperSync().insert(_url, tokens),
Helper().insert(token),
]);
If you need to order them, then create await Future.wait batch instead like your example. For example, first priorities inside the first Future.wait, seconds are after first Future.wait bla bla...