Reputation: 11
I am trying to automate adding items to cart in online shop, however, I got stuck on a loop that should differentiate whether item is available or not.
Here's the loop:
while True:
#if ???
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//*[text()='" + size.get() + "']"))).click()
sleep(1)
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//*[text()='Add to cart']"))).click()
sleep(1)
print("Success!")
break
else:
driver.refresh()
sleep(3)
If the size is available, button is active:
<div class="styles__ArticleSizeItemWrapper-sc-dt4c4z-4 eQqdpu">
<button aria-checked="false" role="radio" class="styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs">
<span class="styles__StyledText-sc-cia9rt-0 styles__StyledText-sc-1n1fwgw-2 styles__ArticleSizeItemTitle-sc-1n1fwgw-3 gnSCRf cLhSqA bipwfD">XL</span>
<span class="styles__StyledText-sc-cia9rt-0 ffGzxX">
</span>
</button>
</div>
If not, button is inactive:
<div class="styles__ArticleSizeItemWrapper-sc-dt4c4z-4 eQqdpu">
<button disabled="" aria-checked="false" role="radio" class="styles__ArticleSizeButton-sc-1n1fwgw-0 fBeTLI">
<span class="styles__StyledText-sc-cia9rt-0 styles__StyledText-sc-1n1fwgw-2 styles__ArticleSizeItemTitle-sc-1n1fwgw-3 gnSCRf cLhSqA bipwfD">XXL</span>
<span class="styles__StyledText-sc-cia9rt-0 styles__StyledText-sc-1n1fwgw-2 kQJTJc cLhSqA">
</span>
</button>
</div>
The question is: what should be the condition for this loop?
I have tried something like this:
if (driver.find_elements(By.XPATH, "//*[contains(@class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and text()='" + e2.get() + "']")):
EDIT: Replaced "=" with "," in the above code as follows:
if (driver.find_elements(By.XPATH, "//*[contains(@class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and text()='" + e2.get() + "']")):
but I keep getting invalid xpath expression error.
EDIT: The error is gone, but the browser keeps refreshing with the else statement (element not found).
Upvotes: 0
Views: 1124
Reputation: 11
I managed to get it working using this condition:
if (driver.find_elements(By.XPATH,
"//*[contains(@class, 'styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs')
and .//*[text()='" + e2.get() + "']]")):
It is quite similar to the original approach, however, adding .//*
before text()
did the trick.
Without .//*
find_elements
was looking in the same node which resulted in not finding the element. .//*
instructs find_elements
to look in the child node where element exists.
Important: text condition was wrapped in additional []
brackets.
Upvotes: 0
Reputation: 9969
e3="Some value"
x=f"//button[contains(@class,'styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and not(contains(@disabled='')) and ./span[contains(text(),'{e3}')]])]"
print(x)
Try looking for the button which contains that class and with that span and maybe check if button disabled?
Upvotes: 0
Reputation: 3215
I believe your error is in the use of the contains
function, which expects two parameters: a string and a substring, although you're passing it a boolean expression (@class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs'
).
I expect this is just a typo and you actually meant to type contains(@class, 'styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs')
(NB comma instead of an equals sign after @class
).
Also, you are looking for a button
element which has a child text node (text()
refers to a text node) which is equal to the size you're looking for, but that text node is actually a child of a span
which is a child of the button
. You can compare your size to the text value of that span
.
Try something like this:
"//*[contains(@class='styles__ArticleSizeButton-sc-1n1fwgw-0 jIVZOs') and span='"
+ e2.get()
+ "']"
Upvotes: 1