How to .click() on a JavaScript object? - javascript

I'm currently working with selenium chromedriver in python and I want to collapse this open.
<a id="pp-T0-81" href="javascript:void(0)" data-action="a-expander-toggle" class="a-expander-header a-declarative a-expander-inline-header pmts-apply-claim-code a-spacing-base a-link-expander" data-a-expander-toggle="{"allowLinkDefault":true, "expand_prompt":"", "collapse_prompt":""}"><i class="a-icon a-icon-collapse"></i><span class="a-expander-prompt"><span class="a-size-base xh-highlight">Voer een cadeaubon- of promotiecode in.</span></span></a>
However the id="pp-T0-81" seems to change when the page is refreshed.
Not very experienced but I tried to use Xpath but that didn't seem to work.

It's hard to know what XPath makes sense in your scenario, but if you think data-action and class are unique and will stay stable (you say that id kept changing), then you could use those two:
const paragraphCount = document.evaluate( `//a[#data-action='a-expander-toggle'][#class='a-expander-header a-declarative a-expander-inline-header pmts-apply-claim-code a-spacing-base a-link-expander']`, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue
console.log(paragraphCount)
<a id="pp-T0-81" href="javascript:void(0)" data-action="a-expander-toggle" class="a-expander-header a-declarative a-expander-inline-header pmts-apply-claim-code a-spacing-base a-link-expander" data-a-expander-toggle="{"allowLinkDefault":true, "expand_prompt":"", "collapse_prompt":""}"><i class="a-icon a-icon-collapse"></i><span class="a-expander-prompt"><span class="a-size-base xh-highlight">Voer een cadeaubon- of promotiecode in.</span></span></a>

Using dynamic id's for testing isn't really a reliable idea. I'd suggest using DOM nesting to target the element.

Related

Selenium No Such Element Exception - Python

I need to automate some stuff behind some hyperlinks from my university's SAP Portal. I figured using Selenium is the way to go here. But it turns out most of the web elements there are faked and created from JavaScript, that is probably why webdriver cannot SEE them.
Here is what I have to click:
<a class="urLnkDragRelate" id="Link6c5f851b" ct="LN" st="" tabindex="0" ti="0" title="Feedback Form" onkeydown="return (sapUrMapi_Link_activate('Link6c5f851b',event))" href="javascript:void(0)" target="" onclick="return htmlbDoEvent(this,'C','onclick','0','htmlb_222143_0',6,1,'',0);">
<span class="urFontStd">
<span ct="TV" class="urTxtStd">Feedback Form</span>
</span>
</a>
Here is the page source : https://pastebin.com/Dpc36nxL
Screenshot for understanding: https://imgur.com/a/qvxhVFA
I tried to use a workaround, by using ActionChains to open up developer console, and inject an artificial CLICK on the desired element, but even that failed because when I try to inject JavaScript at the end, the link here changes each time.
document.querySelector("#Link5908e99d")
Something like this:
assert "Feedback Form" in driver.page_source
# open up the developer console
driver.send_keys(keys.Keys.CTRL+keys.Keys.SHIFT+'i')
driver.perform()
time.sleep(3)
action.send_keys(keys.Keys.ENTER)
# inject the JavaScript...
action.send_keys("document.querySelector("#Link5908e99d").click()"+keys.Keys.ENTER)
action.perform()
How do I go forward with this?
The solution was to switch to the iframe which totally went unnoticed and then find the element using its relative XPath from the iframe.
I think link id is dynamic here and if you want to click on a element then please use below xpath.
locateClick= WebDriverWait(driver, 15).until(EC.visibility_of_element_located((By.XPATH,"//a[contains(text(),'Link')]")))
locateClick.click();

Can't click button with selenium

I'm a newcomer when it comes to javascript and selenium. I have created a simple add to cart project, but the one i am currently working on im having some troubles. The HTML code is:
<div class="buttons-set" id="shipping-method-buttons-container">
<button type="button" class="dark" onclick="shippingMethod.save()" onkeypress="shippingMethod.save()">Continue</button>
<span id="shipping-method-please-wait" class="please-wait icon icon--notch" style="display:none;">
Loading next step... </span>
</div>
I can't seem to figure out anyway where i can click the Continue button. I have tried things such as
driver.findElement(By.linkText("Continue")).click();
driver.findElement(By.xpath(//*[#id='shipping-method-buttons-container']/button)).click();
and many other combinations but none seemed to work.
Try getting the element by its class name:
driver.find_element_by_class_name("dark").click();
I believe you have used implicit wait. If not we need to add it.
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
Also try this below xpath.
driver.findElement(By.xpath("//button[contains(text(),'Continue']")).click();
Hope this helps. Thanks.
Try this below code using cssSelector locator.
driver.findElement(By.cssSelector("button[class='dark'][type='button']")).click();
OR
Try to click the button using java-script executor.
WebElement continue_button = driver.findElement(By.cssSelector("button[class='dark'][type='button']"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", continue_button);

Change data-content in a bootstrap popover

I'm really new to coding, I've searched a bit to try to find an answer and I feel like there's a very simple way to do this, but the answers I find I can't understand.
I have this example which shows the popover.
<span data-toggle="popover" title="Test" data-content="Test"
id="test">popover</span>
I want to change the content of data-content in my JavaScript file
I tried this but it doesn't seem to work.
document.getElementById('test').setAtribute('data-content','hello');
As you are using jquery, try setting the value for content as shown below,
$('#test').data('content', 'hello');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span data-toggle="popover" title="Test" data-content="Test"
id="test">popover</span>
Javascript can be a dangerous tool... it can and will silently do nothing if what you write is not valid Javascript.
So this line:
document.getElementById('test').setAtribute('data-content','hello');
has a misspelling in 'SetAttribute', which tries to call a function that doesn't actually exist (since it's misspelled), and so it does nothing at all.
First step when debugging: re-read your code carefully!

How to resolve NoSuchElement exception in selenium?

I had one link initially. Now I received the requirement of showing button instead of a link for A/B testing. I have to make their ids same since I don't want to write a new test for the button.
To decide which to display I added two unique classes in the li item. This is working fine.
But on testing it starts failing, giving the message "Subscriber link is not available" although button is present there.
I thought that it might failing because of two same ids are there so i added two same classes and change the selector from id to class. But it still failing.
<li class="not_subscriber subscriber-text-link " style="display:none">
<a class="link-orange subscribe" href="" id="subscribe_link"> Subscribe </a>
</li>
<li class="not_subscriber subscriber-orange-btn " style="display:none">
<a class="btn-orange subscribe" href="" id="subscribe_link" > Subscribe </a>
</li>
#FindBy(css = ".subscribe")
#NoSuchElementDescription("Subscriber link is not available")
protected WebElement _subscribeLink;
Is there any way such that i dont have to write new test and change ids and test will start passing??
Can you please try below Xpath:-
//li[#class='not_subscriber subscriber-orange-btn ']/a[#class='btn-orange subscribe']
Hope it will help you :)
Change the selector to xpath. Almost every element has an xpath. And be sure to replace the double quotes to single quotes. It should be more reliable than class or id selectors.

Ghost.py - click specific button

I'm trying to click specific button but with no result yet.
Using Python 3.4.2 and Ghost.py.
<a class="button" title="" ref="1" id="details" href="javascript:void(0);">
</a>
This code is under many div's and li's.
The simplest answer is welcomed!
You can evaluate a line of Javascript with Ghost.py and use the click method on the appropriate DOM element you get with getElementById:
page, resources = ghost.evaluate("document.getElementById('details').click();", expect_loading=True)
UPDATE
To get the link by class use the following line
ghost.evaluate("document.getElementsByClassName('button')[0].click();", expect_loading=True)
There is another version you can use to select and click the first link with an ref="1" attribute on your page:
ghost.evaluate("document.querySelector('a[ref="1"]').click();", expect_loading=True)

Categories