VBA-Wedriver-Selenium-Xpath - Modify Class Value - Click Button -Excel - html

I am opening a website using Chrome Webdriver.
I wanted to Modify value to 12 instead of 10 in a box
HTML Code
<div class="input-currency input-colors">
<input type="tel" autocomplete="off" class="input-currency__input" data-test="deal-amount-input" maxlength="9" value="10" />
<div class="input-currency__values"><span class="input-currency__value">10</span> <span class="input-currency__sign psign">Đ</span></div>
</div>
My Codes
Dim Bot As WebDriver
Dim posts As WebElements, post As WebElement
Set Bot = New WebDriver
Bot.Start "chrome"
Bot.Get "https://olymptrade.com/platform#"
Bot.FindElementsByXPath("//span[contains(#class,'input-currency__value')]").Values = 12
Bot.FindElementByClass("input-currency input-colors").Text
Also there is a button of Buy with Green color, I wanted to click on it.
HTML Code
<div class="deal-buttons__item deal-buttons__item_up">
<button data-test="deal-button-up" class="deal-buttons__button deal-buttons__button_up">
<span>
<span class="deal-buttons__text">80%</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="#FFF" fill-opacity="0.5" class="deal-buttons__svg deal-buttons__svg_arrow">
<path d="M14.6 8l-8.3 8.3a1 1 0 0 0 1.4 1.4L16 9.4V17a1 1 0 0 0 2 0V7a1 1 0 0 0-1-1H7a1 1 0 1 0 0 2h7.6z"></path>
</svg>
</span>
</button>
</div>
My Code
Bot.FindElementsByXPath("//span[contains(#class,'deal-buttons__text ')]").Click
Bot.FindElementsByXPath("//button[contains(#class,'deal-buttons__button deal- buttons__button_up')]").Click
I wanted to change the value and Click on buy button using selenium webdriver
provide me hint on my mistake

FindElements returns a collection. You want a single webElement i.e. a single item of that collection. You need to determine the appropriate index and use that or, if want first match, use methods, for example as shown below, which are singular.
Bot.FindElementByCss(".input-currency input").SendKeys "12" 'though you may need to clear element first
If need to clear first then:
With Bot.FindElementByCss(".input-currency input")
.Clear
.SendKeys "12"
End With
The button html is not provided by you but again you need singular method or index. Assuming want first, and xpath correct:
Bot.FindElementByXPath("//span[contains(#class,'deal-buttons__text ')]").Click

Related

Get second CSS selector selenium vba

I am trying to inspect an element and I have used css selector
Here's the HTML
<div class="MuiPaper-root MuiPaper-elevation0 jss325 MuiPaper-rounded">
<div class="MuiPaper-root MuiPaper-elevation1 jss329 MuiPaper-rounded" style="text-align: right;">
<div class="MuiGrid-root MuiGrid-container">
<div class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-2" style="margin-top: 14px; padding-right: 10px;"><svg class="MuiSvgIcon-root" focusable="false" viewBox="0 0 24 24" aria-hidden="true" role="presentation" style="cursor: pointer;"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"></path></svg></div>
<div
class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-9" style="margin-top: 10px;"><span class="MuiTypography-root jss330 MuiTypography-body1">الرقم الآلي للوحدة 10670235</span><br><span class="MuiTypography-root jss331 MuiTypography-body1">العديلية - قطعة 3 - شارع عيسى عبد الرحمن العسعوسي - قسيمة 129 - منزل 19 - الدور الأرضي - الرقم الآلي للوحدة 10670235</span></div>
</div>
<hr class="MuiDivider-root" style="margin-right: 30px; margin-left: 30px;">
</div>
</div>
I have tried the following css selector span.MuiTypography-root but I found multiple instances. How can I get the desired one only?
The desired text is after the element MuiTypography-root jss331 MuiTypography-body1
I can't use this jss331 as this is created dynamically
You can add more specifiers by just chaining:
span.MuiTypography-root.jss331
This will get any span with classes MuiTypography-root and jss331.
You can chain more as needed.
PS: you can test out selectors by hitting ctrl + f while inspecting the elements. You can type in text to find, CSS selectors, and XPath if I remember correctly
Edit: if a class is dynamic then we have to go by what we know is consistent. If we can assume it will always be the last-child then you can use span.MuiTypography-root:last-child
Or if it's always the third child then span.MuiTypography-root:nth-child(3)
Or (if it's always the second span with the MuiTypography-root class) in whatever app you're using selenium, you can use the find_elements_by_css_selector method, which returns an array, and access the second element found.
So you want to inspect this one MuiTypography-root jss331 MuiTypography-body1
Did you tried this:-
span.MuiTypography-root:last-child{
border: 1px solid;
background-color: gold;
}

XPath for SVG element with fill variable?

I tried to use XPath to select an svg element's fill attribute value, which uses an CSS variable, but I'm getting nothing back.
HTML:
<svg class="unf-icon" viewBox="0 0 24 24" width="24" height="24"
fill="var(--N400, #6C727C)" style="display: inline-block;
vertical-align: middle;">
<path d="M9.5 18a.999.999 0 01-.71-1.71l4.3-4.29-4.3-4.29a1.004 1.004 0 011.42-1.42l5 5a.998.998 0 010 1.42l-5 5a1 1 0 01-.71.29z"></path>
</svg>
XPath attempts:
//*[name()='svg' and fill='#6C727C']
//*[name()='svg' and #fill="#6C727C"]
//*[name()='svg' and #contain(fill, "#6C727C")]
The third try was closest. Change
//*[name()='svg' and #contains(fill, "#6C727C")]
to
//*[name()='svg' and contains(#fill, "#6C727C")]
if you want to check that the fill attribute value has a substring of "#6C727C", or
//*[name()='svg' and #fill="var(--N400, #6C727C)"]
if you want to check that the fill attribute value exactly equals "var(--N400, #6C727C)"
See also
HTML 5, inline SVG, and namespace awareness for SVG DOM
CSS var() function

VBA to click link on webpage with no HREF and contains same class name [duplicate]

I am making an Excel sheet that takes pictures from a webshop and places them on Pinterest.
When I try to submit the image URL I can't find the element to perform a click event.
Full HTML code from Pinterest.
<div data-test-id="website-link-submit-button" class="_50 _5a _6e _h _z7 _4q _j" style="height: 100%;">
<svg class="_u0 _3a _u1 _45" height="20" width="20" viewBox="0 0 24 24" aria-label="Verzenden" role="img">
<title>Verzenden</title>
<path d="M6.72 24c.57 0 1.14-.22 1.57-.66L19.5 12 8.29.66c-.86-.88-2.27-.88-3.14 0-.87.88-.87 2.3 0 3.18L13.21 12l-8.06 8.16c-.87.88-.87 2.3 0 3.18.43.44 1 .66 1.57.66"></path>
</svg>
</div>
I have tried:
Set HTMLButtons = HTMLDoc.getElementsByTagName("div")
For Each HTMLbutton In HTMLButtons
Debug.Print HTMLbutton.className
Next HTMLbutton
and
Set HTMLButtons = HTMLDoc.getElementsByTagName("svg")
For Each HTMLbutton In HTMLButtons
Debug.Print HTMLbutton.className
Next HTMLbutton
but neither of them has given me a useful index that can be combined with a .click event.
=========================================================================
EDIT
There are three steps to get to the code that is mentioned above.
In the picture underneath you will see the three steps.
number three is the button i need to click which when inspected shows the mentioned code.
I am not sure the div is clickable but you can select the div with css attribute = value selector
ie.document.querySelector("[data-test-id='website-link-submit-button']")
You can get the svg with
ie.document.querySelector("[aria-label=Verzenden]")
You can get the path with
ie.document.querySelector("[aria-label=Verzenden] > title + path")
You can click by adding
.click
or
.FireEvent "onclick"
to the end of the above e.g.
ie.document.querySelector("[aria-label=Verzenden]").click
ie.document.querySelector("[aria-label=Verzenden] > title + path").FireEvent "onclick"

Click on an element in Selenium (ElementClickInterceptedException)

I am using Selenium to find information in Kaggle.
In order to do so, I am looking to scrape information on people solutions.
When I navigate to this url: https://www.kaggle.com/allen-institute-for-ai/CORD-19-research-challenge/tasks?taskId=882.
There are people solutions at the end of the task.
I would like to click on those elements.
From the page source, it doesn't look like pressing the solution should navigate to notebook of the solution (the < a href="/{usename} opens the user info tab, and not the notebook tab).
This is how the html of an element looks like:
<li class="sc-qQkIG hIKhtZ">
<a href="/moghazy" target="_blank" rel="noopener" class="sc-pZMVu kiTgMN">
<div class="sc-oTPjJ cCLmQH"><img src="https://storage.googleapis.com/kaggle-avatars/thumbnails/777390-kg.jpg" alt="Moghazy" class="sc-pckkE ljVeKr"><img src="/static/images/avatier/avatier-expert#2x.png" alt="expert" class="sc-pjIPr cvnVIi"></div>
</a>
<div class="sc-qYgLf hNZirj">
<div class="sc-pRStN jTbOhh">
<div class="sc-AxheI sc-fznWqX sc-qanuI frNLaF">COVID-19 Literature Ranking + Web Scraping</div>
</div>
<div class="sc-psdQm hrPHBT"><span class="sc-fzpkJw sc-fznzOf sc-oToFz dtnpxb">Moghazy · <span title="Sat May 16 2020 02:44:32 GMT+0300 (Israel Daylight Time)">6 days ago</span> · Notebook · Python · 4 Comments</span></div>
</div>
<div class="sc-pJsLC cBTgaO">
<div class="sc-pZzGt eDxwsZ sc-pkjoF iehzxN">
<button class="MuiButtonBase-root MuiButton-root sc-oTcWe sc-paYYD hlGLPZ MuiButton-outlined" tabindex="0" type="button" state="no-vote" data-testid="vote-button-icon">
<span class="MuiButton-label label">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="angle-up" class="svg-inline--fa fa-angle-up fa-w-10 " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor" d="M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z"></path>
</svg>
</span>
<span class="MuiTouchRipple-root"></span>
</button>
<button class="MuiButtonBase-root MuiButton-root sc-oTcWe sc-pjUyM kZNtvl MuiButton-outlined Mui-disabled Mui-disabled" tabindex="-1" type="button" disabled="" state="no-vote"><span class="MuiButton-label label">14</span></button>
</div>
</div>
</li>
I find the elements using this code:
elements = driver.find_element_by_class_name("sc-oUaSW").find_elements_by_xpath(".//li")
for element in elements:
element.click()
but I am getting the error:
Message:
element click intercepted: Element ... is not clickable
but when I click on it in the server, it is clickable.
What am I doing wrong?
There are several issues to address:
Element is not clickable because it is not in focus. You need to move to it first.
The click opens a new tab. This requires its own handling.
Moving back to the original tab to click the next item.
This snippet should work:
main_window = driver.current_window_handle #this relates to issues 2, 3
elements = driver.find_element_by_class_name("sc-oUaSW").find_elements_by_xpath(".//li")
for element in elements:
ActionChains(driver).move_to_element(element).click().perform() #this addresses issue 1
#element.click()
driver.switch_to.window(driver.window_handles[1]) #this relates to issue 2
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//a[#class='KernelViewerContext_KernelTitle-sc-rdaqnd chqxNN']")))
#time.sleep(3)
#do whatever you wish with the tab/task here
driver.close()
driver.switch_to.window(main_window) # close tab and switch back to original browser tab (issue 3)
These imports are required for the above to work:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains

Trying to click on the <Button> tag , in selenium web driver using python

I have been trying to click on a button for the following html by using python (selenium webdriver)
<div class="cssm-TopNav_printIcon_2VzB_">
<button type="button" aria-label="Print" title="Print" class="cssm-Button_button_2a549 cssm-Button_secondary_22F7i cssm-Button_sm_EPQ2U">
<div class="" aria-hidden="true" color="black" style="display: inline-block; height: 16px; width: 16px; min-height: 16px; min-width: 16px; max-height: 16px; max-width: 16px;">
<svg viewBox="0 0 24 24" class="" focusable="false">
<g fill="#3C3F51">
<path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z">
</path>
<path d="M0 0h24v24H0z" fill="none">
</path></g></svg></div></button>
<button type="button" class="cssm-Button_button_2a549 cssm-Button_primary_1gH9y cssm-Button_sm_EPQ2U">
<!-- react-text: 314 -->View Custody List<!-- /react-text -->
</button>
I am trying to click on the second button in the above html.
I am using find_element_by_tag because i think for html <button> tag it should work .I am using following code snippet to click on it , but getting-:element not visible
driver.find_element_by_tag_name("button").click()
Any help will be appreciated!!
Selenium with Python documentation UnOfficial
Hii there
Selenium provides the following methods to locate elements in a page:
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
To find multiple elements (these methods will return a list):
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
this is how your code should be
#this code will get the list of tags and select the second tag from the list
element = driver.find_elements_by_tag_name('button')[1]
#this will click the element
element.click()
There is probably more than one button tag on the page, try to be more explicit, like:
driver.find_element_by_class_name("cssm-Button_primary_1gH9y").click()
or even better, give the button an ID and use
driver.find_element_by_id("the-button-id").click()