I try to use VBA and Selenium to make Automate data entry from excel for my work. However, I am still in the beginning. And I got a problem I want to click on Reserve / Contact Guest, so that will make me to do the Next step of writng my code.
I tried FindElementsByClass & FindElementsByCss & FindElementsById & FindElementsByXpath. But did not work.
This my code:
Option Explicit
Dim HJ As New WebDriver
Sub Test()
Dim keys As New SeleniumWrapper.keys
HJ.Start "chrome"
'link for webpage
HJ.Get "http:// "
'Full Screen
HJ.Wait 1000
HJ.Window.Maximize
'Username
HJ.Wait 1000
HJ.FindElementById("ctl00_SplitterRoot_LoginContent_tbUserName_I").Click
HJ.FindElementById("ctl00_SplitterRoot_LoginContent_tbUserName_I").SendKeys ("")
'Password
HJ.Wait 1000
HJ.FindElementById("ctl00_SplitterRoot_LoginContent_tbPassword_I_CLND").Click
HJ.FindElementById("ctl00_SplitterRoot_LoginContent_tbPassword_I").SendKeys ("")
'Checkbox
HJ.Wait 1000
HJ.FindElementById("ctl00_SplitterRoot_LoginContent_chkKeepMeIn").Click
'Log in
HJ.Wait 1000
HJ.FindElementById("ctl00_SplitterRoot_LoginContent_btnLogin_CD").Click
'Only one page
HJ.Wait 1000
HJ.FindElementById("ctl00_SplitterRoot_chkPin_S_D").Click
'CRM
HJ.Wait 1000
HJ.FindElementById("ctl00_SplitterRoot_RootContent_ASPxFormLayout_cmdModule7").Click
'Reserve / Contact Guest (HERE THE PROBLEM With All My Tries)
HJ.Wait 1000
'HJ.FindElementByXPath("//*[#id='ctl00_contentSplitter_menuMain_I0i0_']").Click
'HJ.FindElementById("ctl00_contentSplitter_menuMain_I0i0_").Click
'Set CRMs =HJ.FindElementByClass("dxnb-item dxnb-link dxnb").Click
'For Each CRM In CRMs
''Debug.Print CRM.Text
'Next CRM
'HJ.FindElementByXPath("/html/body/form/div[3]/table[1]/tbody/tr/td[1]/div/div/ul/li/ul/li[1]/span").Click
'HJ.FindElementByCss("#ctl00_contentSplitter_menuMain_I0i0_ > span").Click
'HJ.FindElementsByClass("ctl00_contentSplitter_menuMain_I0i0_")(1).Click
'HJ.FindElementById("ctl00_contentSplitter_Maincontent_imAddNew").Click
End Sub
I want to click to Reserve / Contact Guest:
This is webpage:
enter image description here
To click() on the element with text as Reserve / Contact Guest you can use either of the following locator strategies:
Using FindElementByXPath and the text Reserve / Contact Guest:
HJ.FindElementByXPath("//span[#class='dx-vam' and contains(., 'Reserve / Contact Guest')]").Click
Using FindElementByXPath and the text Reserve:
HJ.FindElementByXPath("//span[#class='dx-vam' and starts-with(., 'Reserve')]").Click
Using FindElementByXPath and the text Contact Guest:
HJ.FindElementByXPath("//span[#class='dx-vam' and contains(., 'Contact Guest')]").Click
References
You can find a couple of relevant detailed discussions in:
Click OK in popup using Selenium VBA
Related
I am having trouble with code while trying to take the class name. I have tried and run time error 32 is appearing as:
InvalidSelector Error: compund class names not permitted
Maybe somebody canhelp with the code below. I have chrome browser 103.5060.114 but web driver 103.5060.56 . I could not find other driver to wnload.
HTML:
<span dir="auto" title="Customer" class="ggj6brxn gfz4du6o r7fjleex g0rxnol2 lhj4utae le5p0ye3 l7jjieqr i0jNr">Customer</span>
VBA code:
Sub iselementpresenttest()
Dim bot As New WebDriver
Dim ks As New Keys
'Init New Chrome instance & navigate to WebWhatsApp
bot.Start "chrome", "https://web.whatsapp.com/"
bot.Get "/"
bot.Window.Maximize
MsgBox "Please scan the QR code. After you are logged in, please confirm this message box by clicking 'ok'"
bot.Wait (3500)
' If bot.FindElementByClass("_2qo4q _3NIfV") = 1 Then
' Debug.Print "true"
'End If
If bot.FindElementByClass("ggj6brxn gfz4du6o r7fjleex g0rxnol2 lhj4utae le5p0ye3 l7jjieqr i0jNr") = 1 Then
' If bot.FindElementByXPath("//*[#id='pane-side']/div/div/div/div[11]/div/div/div[2]/div[2]/div[1]/span/div/span") = 1 Then
Debug.Print "true"
End If
' If bot.FindElementsByXPath("//*[#id='main']/div[3]/div/div[2]/div[3]/div[20]/div/div[1]/div[1]/div[2]/div/div/span").Count > 0 Then
If bot.FindElementsByXPath("//*[#id='main']/div[3]/div/div[2]/div[3]/div[20]/div/div[1]/div[1]/div[2]/div/div/span").Count > 0 Then
bot.TakeScreenshot.ToExcel.PasteSpecial (xlPasteAll)
bot.Quit
MsgBox "Yes"
Else
bot.Quit
MsgBox "NO"
End If
End Sub
My aim is to take the send receive whatsapp icon to the excel sheet
You need to take care of a couple of things here:
The classnames of the <span> looks dynamic and and may change sooner or later, even may be next time you access the application afresh.
Selenium doesn't permit compund class names
Solution
To identify the element you can use the following locator strategies:
Using FindElementByCss:
bot.FindElementByCss("span[title='Customer']")
Using FindElementByXPath:
bot.FindElementByXPath("//span[#title='Customer' and text()='Customer']")
I am very new to Selenium and I'm trying to create an application, which gets some information from an excel sheet, logs into a specific facebook page (not a person's profile), and creates a post which contains an image.
So far I've managed to log into the page account but I have no clue on how to upload a certain image due to the fact that it seems that the webdriver cannot interact with the filedialog that appears if I (programmatically) click on the "upload image" button. Also I cannot find any "upload" id or whatsoever.
Posting here the code I need help with:
' After having logged in, this creates a post
Dim ele As WebElement
Dim drv As New WebDriver
Set ele = drv.FindElementByXPath("//*[#aria-label='Crea un post']") ' This selects the "create a new post" button
ele.Click
Application.Wait (100)
If Not IsEmpty(Cells(24, 2)) Then ' Adds picture if there is one specified in the excel sheet
Set ele = drv.FindElementByXPath("//*[#aria-label='Foto/video']") ' This clicks the "add Picture" button, but then the FileDialog appears and I cannot interact with it
ele.Click
ele.SendKeys "C:\mytestimage.png"
End If
Set ele = drv.FindElementByXPath("//*[#aria-label='Scrivi qualcosa a mypage']") ' Italian for "write something to mypage"
ele.SendKeys "Whatever I want to be written in the post"
I'm trying to click on the Load More button located at the bottom of the left window of this webpage using vba in combination with selenium but the script always throws timeout error pointing at this .Get Url line. Although it seems I've defined an accurate xpath to locate the element, I can't think further as to what I should do now to achieve the same.
How can I click on that Load More button?
Sub ClickOnLoadMore()
Const Url$ = "http://www.ratemyprofessors.com/search.jsp?queryoption=TEACHER&queryBy=schoolDetails&schoolID=457&schoolName=James+Madison+University&dept=select"
Dim driver As New ChromeDriver, post As Object
With driver
.Get Url
Set post = .FindElementByXPath("//div[contains(.,'Load More')]")
.ExecuteScript "arguments[0].scrollIntoView();", post
post.Click
End With
End Sub
I see two "Load More" buttons. Both are matched by "//div[contains(.,'Load More')]". The first one is hidden. You need to handle second one.
Try this XPath
"//div[#class='content' and . = 'Load More']"
At least for me there were a couple of banners to dismiss as well as scrolling. There was no problem with the get line
Option Explicit
Public Sub ClickOnLoadMore()
Const Url$ = "http://www.ratemyprofessors.com/search.jsp?queryoption=TEACHER&queryBy=schoolDetails&schoolID=457&schoolName=James+Madison+University&dept=select"
Dim driver As New ChromeDriver, post As Object
With driver
.get Url
If .FindElementsByCss(".close-notice.close-this").Count > 0 Then
.FindElementByCss(".close-notice.close-this").Click
End If
.SwitchToFrame .FindElementByCss("[id^='spout-unit-iframe']")
With .FindElementByCss("#spout-ads #spout-header-close")
.ScrollIntoView
.Click
End With
.SwitchToDefaultContent
.ExecuteScript "document.querySelector('.result-list [onclick*=LoadMore]').scrollIntoView(true);" & _
"window.scrollBy(0, -(window.innerHeight - this.clientHeight) / 2);"
.FindElementByCss(".result-list [onclick*=LoadMore]").Click
Stop '<== Delete me later
'other code
.Quit
End With
End Sub
I'd like to use selenium VBA to download some data from Yahoo Finance KOSPI COmposite Index.
I got the difficulty when click the date picker arrow to get the mini window to select the end date as today. I tried to record the marco through selenium IDE in chrome, but IDE does not record the step when I click the arrow of the Time period to get the date picker visible.
Below is my code in VBA.
Public Function seleniumKorea(bot As WebDriver)
Dim url As String
url = "https://finance.yahoo.com/quote/%5EKS11/history?period1=1484018309&period2=1515554309&interval=1d&filter=history&frequency=1d"
bot.Start "chrome", url
bot.Get "/"
'Not sure how to add date picker here
bot.FindElementByName("endDate").Clear
bot.FindElementByName("endDate").SendKeys (Date)
bot.FindElementByXPath("(.//*[normalize-space(text()) and normalize-space(.)='End Date'])[1]/following::button[1]").Click
Application.Wait (Now + TimeValue("0:01:00"))
bot.FindElementByXPath("(.//*[normalize-space(text()) and normalize-space(.)='As of'])[1]/following::div[4]").Click
Application.Wait (Now + TimeValue("0:01:00"))
bot.FindElementByXPath("(.//*[normalize-space(text()) and normalize-space(.)='Currency in KRW'])[1]/following::span[2]").Click
Application.Wait (Now + TimeValue("0:01:00"))
End Function
I tried to use the ByXPath to get the svg class but failed.
Thanks in advance.
I would use the following which submits the OATH consent if required and scrolls the date picker into the viewport
Option Explicit
Public Sub DatePicking()
Dim d As WebDriver
Set d = New ChromeDriver
Const URL = "https://finance.yahoo.com/quote/%5EKS11/history?period1=1484018309&period2=1515554309&interval=1d&filter=history&frequency=1d/"
With d
.get URL
If .Title = "Yahoo is now part of Oath" Then
.FindElementByCss("form").submit
End If
With .FindElementByCss("[data-test='date-picker-full-range']")
.ScrollIntoView
.Click
End With
With .FindElementByCss("[name=startDate]")
.Clear
.SendKeys "05/10/2017"
End With
With .FindElementByCss("[name=endDate]")
.Clear
.SendKeys "05/10/2017"
End With
Stop '<==Delete me later
.Quit
End With
End Sub
Check this out. It should serve the purpose. I used xpath to solve the issue.
Sub CustomizeDate()
Const Url$ = "https://finance.yahoo.com/quote/%5EKS11/history?period1=1484018309&period2=1515554309&interval=1d&filter=history&frequency=1d"
Dim driver As New ChromeDriver
With driver
.get Url
.FindElementByXPath("//input[#data-test='date-picker-full-range']", timeout:=5000).Click
.FindElementByXPath("//input[#name='startDate']").Clear.SendKeys ("01/05/2017")
.FindElementByXPath("//input[#name='endDate']").Clear.SendKeys ("01/08/2017")
.FindElementByXPath("//button/span[.='Done']", timeout:=5000).Click
.FindElementByXPath("//button/span[.='Apply']", timeout:=5000).Click
End With
End Sub
Don't use hardcoded delay for any item to appear. Use Explicit Wait instead. The script will wait upto 5000, meaning 5 seconds for that item to be available.
I am trying to automate the process of data collection from the following website.
I failed already at the first task, which is clicking the buttons and submitting a postal code.
The first part of the code should click the left button Pflegeeinrichtungen und Betreuungsangebote, which expands the selection by 4 buttons.
Afterwards the second button stationäre Pflegeeinrichtung should be clicked to expand the selection even further.
The last selection should be Vollstationäre Pflege.
To change the state of the searchButton to clickable a postal code must be entered in the searchBar, which presents proposals based on the entered postal code. One of those proposals must be selected to change the state of the searchButton, just entering the postal code is not enough.
So far I managed to click the second (2.) and third (3.) button and enter a postal code in the searchBar. Excel opens the IE window and clicks the buttons, but since the first (1.) button was not clicked beforehand it does not even show the 2. and 3. button. If i click the first button manually after executing the VBA code I can see that the 2. and 3. button are selected.
My Questions are:
How do I click the first button via VBA?
How do I submit the search for the entered postal code?
How do I choose one of the proposals ? (It does not even matter which one.)
I managed to click the buttons via:
.getElementById("ctl00_ContentPlaceHolder1_suche_btn_versorgung2").Click
and
"ctl00_ContentPlaceHolder1_suche_btn_pflegeart1" for "vollstationäre Pflege"
Thank you very much in advance
In the end I gave in and used selenium basic VBA wrapper and here is how you do what you are after with VBA. You can use other supported browsers apart from Chrome.
Code:
Option Explicit
Public Sub test()
Dim d As WebDriver
Set d = New ChromeDriver
Const DATA_OPTION As Long = 1 '<== 1 bist Pflegeeinrichtungen und Betreuungsangebote , oder für Pflegeberatung verwenden 2: .....("button[data-tab=""2""]")
Const LOCATION As String = "10777 Berlin/Schöneberg" '<== Wo möchten Sie suchen?
Const CARE_SETTING As Long = 1 '<== 1 für Ambulanter Pflegedienst. Oder: 2.Stationäre Pflegeeinrichtung ; 3.Angebote zur Unterstützung im Alltag ; 4. Häuslicher Betreuungsdienst
With d
.Start "Chrome"
.Get "https://www.pflegelotse.de/(S(x2hdp4ld1i0ok4y0q2upqasz))/presentation/pl_startseite.aspx"
.FindElementByCss("button[data-tab=""" & DATA_OPTION & """]").Click
Application.Wait Now + TimeSerial(0, 0, 1)
.FindElementByCss("button[data-value=""" & CARE_SETTING & """]").Click
.FindElementById("ctl00_ContentPlaceHolder1_suche_bezirk").SendKeys LOCATION
Application.Wait Now + TimeSerial(0, 0, 1)
Dim keys As New keys
.SendKeys keys.Enter
Application.Wait Now + TimeSerial(0, 0, 1)
.FindElementById("ctl00_ContentPlaceHolder1_suche_btn_suche").Click
Stop
.Quit
End With
End Sub
In action: