Unable to access the elements in iframe in Puppeteer - selenium

await page.isElementVisible('iframe');
console.log('iframe is ready. Loading iframe content');
const elementHandle = await page.waitForSelector("iframe[id='payment-form']");
const frame = await elementHandle.contentFrame();
its working till this point
// console.log('filling form in iframe');
const cardType = await frame.$x(`//div[contains(#class, 'css-12kbcej')]//select[#data-elid="card-type"]`);
await page.click();
also try to do this one as well
await page.waitForXPathAndClick(`//div[contains(#class, 'css-12kbcej')]//select[#data-elid="card-type"]`);
and this as well
const cardType = await frame.$x(`//div[contains(#class, 'css-12kbcej')]//select[#data-elid="card-type"]`);
await frame.click(cardType);
But nothing works out
Error Message
Error: Evaluation failed: DOMException: Failed to execute 'querySelector' on 'Document': The provided selector is empty.
at puppeteer_evaluation_script:1:33

You have await page.click(); -- page.click() requires a selector, eg page.click('myCssSelector'). That's why you're getting that error, The provided selector is empty

Related

How to fix assertion error using playwright?

I'm using playwright to do e2e testing to check if the email is exists or not, and while I run my tests its said :
"Finished test flow with status passed"
But its show me that the test is failed because i have assertion error and not because i do something wrong
this is a piece my code:
const fillEmail = async (page: Page, value: string) =>
await page.fill("email-for-test", value);
const fillPassword = async (page: Page, value: string) =>
await page.fill("password-for-test", value);
await fillName(page, name);
await fillEmail(page, email);
const res = await page.locator('.email-error').innerText(); // return error string
expect(res).toContain("Email is already in used");
and i got error, you can see in the picture that I uploaded
any idea how to remove or fix this error
You code actually works. You can also use page.textContent()
const res = await page.locator('.email-error').innerText();
expect(res).toContain("Email is already in use");
const text = await page.textContent('.email-error');
expect(text).toContain("Email is already in use");
How about you just use this:
await expect(page.locator('.email-error')).toContainText(
'Email is already in used',
{timeout: 7000}
)
Also Check if the last word of the assertion message is used or use.
You can also use the text selector and assert it to be visible. Something like this:
await expect(page.locator('text=Email is already in use')).toBeVisible({
timeout: 7000,
})
i soulve this one by upgrade playwright library,
From v1.15 to v1.25

Unable to interact with elments using $$ sign in WebdriverIO

I'm using WebdrivreIO(v7) but unable to export $$ value from another file. If I'm working with the same file it's working fine, but another file not working. not sure what's wrong here
sample.js
module.exports = {
details: $$('.agent-rows p.name'),
}
script_file.js
When("Getting the list from the listing page"){
const sample=require("./sample.js");
console.log("value 1"+ await sample.details) // Output : nothing empty
console.log("value 2"+ await sample.details[0]) // Output : undefined
}
are you sure you are not doing any thing between constant sample, console.log lines? require will trigger the details property as soon as you call it .
so if you are trying the below thing , it won't work
const elem = sample.details
//do something for the element to be present
(await elem)[0].dosomething
because sample.details will trigger the fetch process before the element is present. await is used to wait for an async process to complete, not to trigger it.
use instead:
module.exports = {
details: ()=>{$$('.agent-rows p.name')},
}
in code:
const elem = sample.details
//do something for the element to be present
(await elem())[0].dosomething //here you are triggering the fetch
It seems you have a typo s. It should be sample.detail not sample.details.
When("Getting the list from the listing page"){
const sample=require("./sample.js");
console.log("value 1"+ await sample.detail) // 'detail' not 'details'
}

Protractor: How to properly wait after a click?

I am using Protractor for e2e testing. The tests should first enter too short username and passwords and because of Angular validators when clicked on a submit button (which is disabled) get rejected and stay put (this works!), then it should enter an username of correct length with also a password of a correct length, click on the submit button and NOT get redirected, because it's a false login. This fails... The last test requires to input correct login details and click on submit and should get redirected to the dashboard.
According to this answer https://stackoverflow.com/a/21785088/12360035 is all it would take to solve my problem that seems to throw the
- Failed: script timeout
(Session info: chrome=79.0.3945.130)
(Driver info: chromedriver=79.0.3945.16 (93fcc21110c10dbbd49bbff8f472335360e31d05-refs/branch-heads/3945#{#262}),platform=Windows NT 10.0.18362 x86_64)```
error for both of my tests.
How do I fix this?
My tests are written this way:
it('should enter too short username and password and NOT get redirected => stay put', () => {
element(by.css('#inputUser')).sendKeys('bah');
element(by.css('#inputPassword')).sendKeys('bah');
const btn = element(by.css('#loginSubmit'));
btn.click();
const curUrl = browser.getCurrentUrl();
expect(curUrl).toBe('http://localhost:4200/avior/login');
});
it('should enter incorrect username and password and NOT get redirected => stay put', () => {
const ele1 = element(by.css('#inputUser'));
const ele2 = element(by.css('#inputPassword'));
const btn = element(by.css('#loginSubmit'));
ele1.clear();
ele2.clear();
ele1.sendKeys('bah');
ele2.sendKeys('bahbahbah');
btn.click();
browser.waitForAngular();
const curUrl = browser.getCurrentUrl();
expect(curUrl).toBe('http://localhost:4200/avior/login');
});
it('should enter correct username and password and get redirected to /avior/dashboard', () => {
const ele1 = element(by.css('#inputUser'));
const ele2 = element(by.css('#inputPassword'));
const btn = element(by.css('#loginSubmit'));
ele1.clear();
ele2.clear();
ele1.sendKeys('Chad');
ele2.sendKeys('chadchad');
btn.click();
browser.waitForAngular();
const curUrl = browser.getCurrentUrl();
expect(curUrl).toBe('http://localhost:4200/avior/dashboard');
});
UPDATE
A jwt token is sent as a cookie in response, that might be part of the problem. I can't seem to find info online on how to handle cookies with Protractor..
Waits in Protractor
Wait for the element to Present
this.waitForElementPresent = function (element) {
return browser.wait(() => (element.isPresent()), 30000);
}
Wait for the element to Display
this.waitForElementDisplayed = function (element) {
return browser.wait(() => (element.isDisplayed()), 30000);
}
Sleep Condition
this.sleep = function (sec) {
browser.sleep(sec * 1000);
}
Expected Conditions
this.waitForElementVisibility = function () {
let EC = ExpectedConditions;
return browser.wait(EC.visibilityOf(), 30000);
}
According to this question Failed: script timeout: result was not received in 11 seconds From: Task: Protractor.waitForAngular() - Locator: By(css selector, #my-btn) adding browser.waitForAngularEnabled(false); before the button clicks seems to have solved the errors..

How to use cryptocomapre api to display price of BTC?

I'm working on an electron app and im using cryptocompare api to display BTC price but it dosen't displays. I've tried every solution i could think of, some help would be appreciated!!
const electron = require('electron');
const path = require('path');
const BrowserWindow = electron.remote.BrowserWindow;
const axios = require('axios');
const notifyBtn = document.querySelector('.notify-btn');
const price = document.querySelector('.price');
const targetPrice = document.querySelector('.target-price');
function getBTC(){
const cryptos = axios.get('https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD&api_key={api_key}')
price.innerHTML = '$'+cryptos
}
getBTC();
setInterval(getBTC, 20000);
It gives me an output of '$[object Promise]'
In the documentation for axios, it says you need to do this instead:
axios.get(url)
.then(function (response) {
// do something with response
});
This is because the value returned by axios.get isn't a response, it's a promise that will resolve to a response. (So it gets coerced to the string [object Promise].) If you don't know what this means, read this link. Basically promises are a way of dealing with tasks that take a long time to run (such as api calls) without blocking other javascript code from runnning. But anyway, what you want is this:
function getBTC(){
axios.get('https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD&api_key={api_key}')
.then(function(response) {
var data = response.data;
var cryptos = // get cryptos from data somehow
price.innerHTML = '$'+cryptos;
});
}
I haven't read the axios documentation in detail. I believe what you are looking for is in response.data, but I couldn't tell you any more than that. Try console.log('Response:', response); to find out how the response is structured.

Unable to find element and send keys

So just a brief overview, I'm unable to send keys to a edit text field for android. I've successfully sent keys to this element via browser but in order to test the mobile application fully, I'd like to run e2e tests on a device using Appium.
I've successfully got Appium to click button elements but am having a hard time getting it to send keys to an edit field element.
Am I able to find elements by model when testing with android as I have set in my forgot-pin-page.js?
pin-reset-page.js
var pinResetPage = function() {
describe('The Reset Pin Flow', function () {
forgotPinPage = forgotPinPageBuilder.getForgotPinPage(),
describe('The Forgot Pin Page', function () {
it('should allow the user to enter their MSISDN and continue',
function () {
forgotPinPage.enterMsisdn('123123123');
forgotPinPage.doForgotPin();
expect(securityPage.isOnSecurityPage()).toBe(true);
});
});
}
forgot-pin-page.js
'use strict';
var ForgotPin = function () {
var forgotPinPageContent = element(by.id('forgot')),
msisdnInput = element(by.model('data.msisdn')),
return {
enterMsisdn: function (msisdn) {
return msisdnInput.sendKeys(msisdn);
}
};
module.exports.getForgotPinPage = function () {
return new ForgotPin();
};
The error i'm getting is
? should allow the user to enter their MSISDN and continue
- Error: Timeout - Async callback was not invoked within timeout spe
cified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Not sure if this is the correct solution but it worked for me. I downgraded jasmine2 to jasmine and that seemed to resolved the async timeouts I was having.