Targeting DOM elements from parent to grand parent produces different result - python-3.x

I am using selenium to target 3 buttons as in the image below
Here is the code for each thumbnail
<div class="product">
<div class="product-image">
<img src="./images/raspberry.jpg" alt="Raspberry - 1/4 Kg">
</div>
<h4 class="product-name">Raspberry - 1/4 Kg</h4>
<p class="product-price">160</p>
<div class="stepper-input">
–
<input type="number" class="quantity" value="1">
+
</div>
<div class="product-action">
<button class="" type="button">ADD TO CART</button>
</div>
</div>
When I try the following code below it fulfills the goal of clicking the 3 buttons
add_cart_btn_locator = (By.CSS_SELECTOR, "div[class='product'] button")
add_cart_btn_link = driver.find_elements(*add_cart_btn_locator)
for i in add_cart_btn_link:
i.click()
But when I try to change my selector to div[class='product-action'] button, only the first button is clicked then the below error appears
Message: stale element reference: element is not attached to the page document
May I kindly ask what is the difference of the two locators and why they do not work identically?

change your loop :
add_cart_btn_locator = (By.CSS_SELECTOR, "div[class='product-action'] button")
add_cart_btn_link = driver.find_elements(*add_cart_btn_locator)
nbrlinks = len(add_cart_btn_link)
for i in range(nbrlinks):
add_cart_btn_locator = (By.CSS_SELECTOR, "div[class='product-action'] button")
add_cart_btn_link = driver.find_elements(*add_cart_btn_locator)
add_cart_btn_link[i].click()
you have to reload the search of items each time

Related

VBA selenium <div button class span> tried to click click

I have this case where i cannot click the button.
It seems to be Span within span, how to use this on VBA?
<div class=" detail-section">
<span class="btn click-back">
<span> << Back to Fill</span>
</span>
<button class="btn click-primary">
<span>Create Detail</span>
</button>
</div>
i tried and it doesn't work
Obj.FindElement(By.XPath("//*[contains(#span, 'Create Detal')] ")).Click
I got the answer and working fine now.
Obj.FindElementByXPath("//button[#class ='btn click-primary']").Click

element not clickable for radio options

I am trying to find all elements by using find_element_by_xpath. In the below web elements, I am looking for these three elements separetely:
1. <label for="hw-log-mode-none" class="ng-binding">None</label>
2. <label for="hw-log-mode-session" class="ng-binding">Per-Session</label>
3. <label for="hw-log-mode-mapping" class="ng-binding">Per-Mapping</label>
<div class="field ng-scope" ng-if="!isTransparentMode && showNatPool && !policy.isIPv6" ng-show="policy.action == 'accept' && policy.nat == 'enable'">
<label class="ng-binding">Hardware Logging Mode</label>
<div>
<div class="radio-group">
<input type="radio" id="hw-log-mode-none" value="none" ng-model="policy['hw-logging-mode']" class="ng-pristine ng-untouched ng-valid" name="670">
<label for="hw-log-mode-none" class="ng-binding">None</label>
<input type="radio" id="hw-log-mode-session" value="session" ng-model="policy['hw-logging-mode']" class="ng-valid ng-dirty ng-touched" name="671" style="">
<label for="hw-log-mode-session" class="ng-binding">Per-Session</label>
<input type="radio" id="hw-log-mode-mapping" value="mapping" ng-model="policy['hw-logging-mode']" class="ng-valid ng-dirty ng-touched ng-valid-parse" name="672" style="">
<label for="hw-log-mode-mapping" class="ng-binding">Per-Mapping</label>
</div>
</div>
</div>
I can find element #1 and #2 in above list. But when I try to find element #3 using the same way:
elem = driver.find_element_by_xpath("//label[#for='hw-log-mode-mapping']")
I got this error:
Message: element click intercepted: Element ... is not
clickable at point (707, 508). Other element would receive the click:
... (Session info: chrome=77.0.3865.90)
You could try clicking the element using Javascript and see if that works around the error.
elem = driver.find_element_by_xpath("//label[#for='hw-log-mode-mapping']")
driver.execute_script("arguments[0].click();", elem)
If that doesn't work, you could try clicking the input element itself.
elem = driver.find_element_by_xpath("//input[#id='hw-log-mode-mapping']")
driver.execute_script("arguments[0].click();", elem)
Try this, Get list of all the elements as they have same class name as follow:
List<WebElement> elements = driver.findElements(By.xpath(".//label[#class='ng-binding']"));
Now create a method to select the radio options as follow:
public void selectRadioOption(String option){
if(option.equals("None"))
elements.get(0).click();
else if(option.equals("Per-Session"))
elements.get(1).click();
else if(option.equals("Per-Mapping"))
elements.get(2).click();
}
Call this method, pass the option whichever you want to select.
Hope it works for you. You should not find 3 different xpath if you can work with one.

VBA fire event on empty HTML div

I try to automate some manual processes by using VBA automation. One of them is to click on a element that has an empty content and at the moment I am not able to figure out how to deal with it
The HTML code that I am trying to click on:
<div id="searchcombobox-1077-triggerWrap" data-ref="triggerWrap" class="x-form-trigger-wrap x-form-trigger-wrap-toolbar">
<div id="searchcombobox-1077-inputWrap" data-ref="inputWrap" class="x-form-text-wrap x-form-text-wrap-toolbar">
<input id="searchcombobox-1077-inputEl" data-ref="inputEl" type="text" role="combobox" size="1" name="searchcombobox-1077-inputEl" placeholder="Account Number" tabindex="-1" class="x-form-field x-form-text x-form-text-toolbar " autocomplete="off" componentid="searchcombobox-1077">
</div>
<div id="searchcombobox-1077-trigger-picker" class="x-form-trigger x-form-trigger-toolbar x-form-search-trigger x-form-search-trigger-toolbar "></div>
</div>
The VBA code used is:
HTMLDoc.getElementById("searchcombobox-1077-inputEl").Value = '11xx111'
Set click_el = HTMLDoc.querySelector("#searchcombobox-1077-trigger-picker")
With click_el
.Focus
.FireEvent "onclick"
End With
What should be the approach that I need to take into consideration since the div element that I need to click on is empty?
Thanks,

Select Radio Button / input value in Open box on website using vba

I am trying to punch the radio button question and want to input the value in an open text box as well (using VBA). Below is the script I am using.
I tried multiple things, looked at other websites as well but it is not working.
It would be great if someone can guide me.
Dim IE As Object
Dim Region, VOCSentDate As String
Sheets("Sheet1").Select
Region = ThisWorkbook.Worksheets("Sheet1").Range("A1").Value
VOCSentDate = ThisWorkbook.Worksheets("Sheet1").Range("B1").Value
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "website link....."
Application.StatusBar = "Submitting"
While IE.Busy
DoEvents
Wend
I'm not sure how to punch the radio button question. I tried the 3 types for Open textbox below but none of them are not working, throwing object required error
IE.Document.getElementById("ctl00_body_7F22FA6E-5D77-426A-AA84-68D833FA05C1_3").Value = VOCSentDate
IE.Document.getElementById("ctl00_body_7F22FA6E-5D77-426A-AA84-68D833FA05C1_3").innerText = VOCSentDate
IE.Document.all("ctl00_body_7F22FA6E-5D77-426A-AA84-68D833FA05C1_3").Value = VOCSentDate
Application.StatusBar = "Form Submitted"
IE.Quit
Set IE = Nothing
-------------- HTML of the Radio button --------------
<div class="SurveyItem RadioButtonList Item1">
<div class="ItemText">
<span class="NoItemNumber"></span><span class="QuestionText">Please select your region:</span>
</div>
<div class="Validators">
<span id="ctl00_body_ctl12" style="color:Red;display:none;">A response to this question is required</span>
</div>
<div id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" class="Response">
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_1" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_1" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_1">Americas</label>
</div>
<div class="ResponseOption AlternatingRow">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_2" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_2" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_2">ANZ</label>
</div>
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_3" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_3" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_3">APAC</label>
</div>
<div class="ResponseOption AlternatingRow">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_4" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_4" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_4">APME</label>
</div>
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_5" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_5" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_5">Europe</label>
</div>
<div class="ResponseOption AlternatingRow">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6">India</label>
</div>
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_7" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_7" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_7">North America</label>
</div>
------------------- HTML of Open End -------------------------
<div class="SurveyItem Item3">
<div class="ItemText">
<span class="NoItemNumber"></span><span class="QuestionText">EOPR First Sent Date (dd/mm/yyyy)</span>
</div>
<div class="Validators">
<span id="ctl00_body_ctl52" style="color:Red;display:none;">A response to this question is required</span><span id="ctl00_body_ctl53" style="color:Red;display:none;">Incorrect Date Format</span>
</div>
<div class="Response">
<input name="ctl00$body$01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3" type="text" id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3" class="TextBox" />
</div>
</div>
tl;dr;
The following are based on the HTML as shown. If there are parent form/frame/iframe tags involved they will also need to be negotiated before making the selections below.
Radio buttons:
For the radio buttons you can use a CSS selector combination to target the page styling and return a nodeList of all of the radio button elements. You can then select by index the appropriate button
Dim aNodeList As Object
Set aNodeList = ie.document.querySelectorAll(".ResponseOption [type=radio]")
aNodeList.item(0).Click '<==Select first option
I think click may be likely method here as I can't see a checked attribute, else the syntax would be aNodeList.item(0).checked = True
The returned nodeList is as follows by index
Textbox:
There is an ID for the input box so you can use an ID selector, #, to target
ie.document.querySelector("#ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3").Value = "myText"
To choose a radio button style input, make the checked property true.
IE.Document.getElementById("ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6").checked = true
An input textbox gets its value set.
IE.Document.getElementById("ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3").value = format(VOCSentDate, "d/m/yy")

Select a dropdown using Python + Selenium

I am writing an automation for work and am stuck with a dropdown. The particular select box in question is as follows:
<span class="a-dropdown-container" id="select-size-bulk-asin">
<select name="display_type" class="a-native-dropdown">
<option value="SMALL-IMAGES">SMALL-IMAGES</option>
<option value="LARGE-IMAGES">LARGE-IMAGES</option>
<option value="TEXT">TEXT</option>
</select>
<span tabindex="-1" data-a-class="a-spacing-small" class="a-button a-button-dropdown a-spacing-small">
<span class="a-button-inner">
<span class="a-button-text a-declarative" data-action="a-dropdown-button" aria-haspopup="true" role="button" tabindex="0" aria-pressed="false" aria-owns="2_dropdown_combobox">
<span class="a-dropdown-prompt">SMALL-IMAGES</span>
</span>
<i class="a-icon a-icon-dropdown"></i>
</span>
</span>
</span>
It defaults to 'SMALL Images' and I would like to select the 'TEXT' option. I am receiving element not clickable error. The page is simple and the element is visible on the screen.
The list of methods I did try are:
Used WebDriverWait to wait for the element to be visible;
Used WebDriverWait to wait for the element to be clickable;
Used the select class to set the selected option;
I also read through a question.
I am thinking if I should just go to the next element and send Shift+Tabs until I reach this drop down and then down arrow keys. But would like to use that only as the last resort.
NOTE:
- I am using Python 3 and Chrome.
You can try this code to select value from drop down :
select = Select(driver.find_element_by_id('select-size-bulk-asin'))
select.select_by_visible_text('TEXT')
However,as you have mentioned you are receiving element not clickable exception. you can try this code :
WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.ID, "select-size-bulk-asin")))
As a last resort you can go ahead with :
drop_down= driver.find_element_by_id("select-size-bulk-asin")
drop_down.click()
actions = ActionChains(driver)
actions.send_keys(Keys.ARROW_DOWN)
actions.send_keys(Keys.ARROW_DOWN)
actions.send_keys(Keys.ENTER)
actions.perform()

Resources