I currently have selected an item in a web page with the xpath:
*[#id="content_gvNewLeads_tccell0_5"]/a
I need to get each one of these elements, there are about 200 on a page. Each id changes slightly.
I've tried this:
const aLink = await page.$x('//id[contains(content_gvNewLeads_tccel)]/a')
I get an error any idea how I can achieve this?
try this XPath instead:
const aLink = await page.$x('//*[contains(#id,"content_gvNewLeads_tccel")]/a')
Related
I have the following code:
<div class="pt6-sm pb6-sm ta-sm-r d-sm-flx flx-jc-sm-fe"><button class="mb1-sm css-bz0cep ex41m6f0 secondary" type="button">Cancel</button><button class="ml3-sm mb1-sm css-17hmqcn ex41m6f0 primary" type="button">Save</button></div>
I'm attempting to click on the save button and I'm trying this:
const addBtn = await select(page).getElement('button:contains(Save)');
await addBtn.click()
I have also tried:
const [button] = await page.$x("//div[#class='elements']/button[contains(., 'Save')]");
if (button) {
await button.click();
}
I get an unhandled promise rejection. Any idea why?
Basically you get the UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'click' of undefined until either your selector is not correct / element doesn't exist or it haven't yet appeared on the page.
In this case it seems your xpath selector was not grabbing the element.
That will do the job:
const addBtn = await page.$x('//button[contains(text(), "Save")]')
await addBtn[0].click()
Did you know? If you right click on an element in Chrome DevTools "Elements" tab and you select "Copy": there you are able to copy the exact selector or xpath of an element. After that you can switch to the "Console" tab and with the Chrome api you are able to test the selector's content, so you can prepare it for your puppeteer script. E.g.: $x('//button[contains(text(), "Save")]').textContent should show the text of the button that you've expected to click on, otherwise you need to change on the access, or you need to check if there are more elments with the same selector etc. This may helps you to find more appropriate selectors.
I need to extract parts of string from the text which was written in the field (input) on UI (This text is not in HTML code).
I am trying sth like this (but it does not work).
const textInput = await model.inputtTittle.textContent;
console.log(textInput)
Nothing return probably textContent take text from the selector, I was trying with .innerText but it also returned nothing.
And then I would like to write sth like this:
if (textInput.length > 32)
await t.typeText(model.inputTittle, textInput.substr(0, 30));
I hope that it will be work if I have the content of the field inputTittle.
Additional question:
This answer is hidden. This answer was deleted via review 16 hours ago by Jason Aller, Mark Rotteveel, Nico Haase, Botje.
This code works:
const textTittle = await model.inputTittle.value;
const textlength = textTittle.length
if (textlength>32)
{
console.log(textTittle.substr(0,30));
}
why i can not to writte shorter:
if (await model.inputTittle.value.length >32)
{ console.log(await model.inputTittle.value.substr(0,30));}
You can obtain the entire DOM Node Snapshot with all properties in one object to check what properties you need. It is likely you need the value property.
I am trying to render polymer template using below code,
const shadowRoot = this.attachShadow({mode: 'open'});
const htmlTemplate = importDoc.querySelector('template');
shadowRoot.innerHTML = htmlTemplate.innerHTML;
But this renders two way binded data also as a string instead of showing the binded value e.g
<h1 id ="contactFooter">{{localize('_testVal')}}</h1>
is displayed as it is do anyone have any idea? Two way binding is just example it renders everything like this.
To use a <template> tag you should use importNode on the content.
e.g.
var clone = document.importNode(htmlTemplate.content, true);
shadowRoot.appendChild(clone);
// note that you will need to clear the shadowRoot if you do rerenderings
// OR you could try
shadowRoot.innerHTML = htmlTemplate.content;
see more details here https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
I have a list of links, and want to click on one of them based on the name of the link. I can't accomplish this with selectors.
It would be nice to use something like page.$eval to get the ElementHandle of that item so I can then tap/click it.
The only other approach I can think of is getting the x/y coords within $eval and then manually clicking on clicking on the location. Seems tedious.
I posted this here per the guidelines, but LMK if we should open a PR on this.
Have you considered use the page.$$(selector) to get all your target elments and then use page.evaluate() to get the linkName, then do the check and click?
something like:
const targetLinks = await page.$$('yourLinkSelector');
for(let link of targetLinks){
const linkName = await page.evaluate(el => el.innerHTML, link);
if (linkName === 'myFancyLinkToClick') {
await link.click();
// break if only 1 link click is needed.
break;
}
}
Hope it works for you.
I'm trying to extract the content of data-id.
For example :
<div data-id= "43434"></div>
How can I get the value of 43434? I want to get access to the content of data.
As I see you want to get this value inside a TestCafe test.
If so you can use the Selector.getAttribute() method.
const element = Selector('your-div-selector');
const attrValue = await element.getAttribute('data-id');
// or if you need to use it in an assertion
await t.expect(element.getAttribute('data-id')).eql('43434');
Get the element using has attribute selector and get the value from dataset property or get attribute value using Element#getAttribte method.
console.log(
document.querySelector('div[data-id]').dataset.id
)
<div data-id="43434"></div>