I'm in the middle of writing a script that enters details into a sign up form.
The first name field of the form has the following html code:
<input name="firstname" class="text-input" id="input-text-view328" aria-describedby="form-input-text-error-view307-required" type="text" maxlength="50" placeholder="" data-event="blur" data-view-value="" data-stickit-id="stickit_47" autocomplete="off">
I can't seem to get the script to enter a value for this field. I have tried each of the following and none seem to work:
Set Fname = IE.Document.getElementsByName("firstname")
Fname.Value = "John"
Set Fname = IE.Document.getElementsByClassName("text-input")
Fname.Value = "John"
Set Fname = IE.Document.getElementByID("input-text-view328")
Fname.Value = "John"
The error i get is
"run-time error '438':
Object doesn't support this property or method"
Any idea what's going on here?
Since getElementsByName returns collection, you can access them with the index nos
IE.Document.getElementsByName("firstname")(0).Value = "John"
OR
Set Fname = IE.Document.getElementsByName("firstname")(0)
Fname.Value = "John"
OR
IE.Document.getElementByID("input-text-view328").Value = "John"
OR
IE.Document.querySelector("#input-text-view328").Value = "John"
Related
I am trying to prefill data from Excel to a local intranet website via VBA.
I've been able to prefill most data to the site, but I am struggling with this combodate box:
Please see HTML code:
<div class="form-group row " id="starttime_field">
<label class="col-form-label col-md-3" for="starttime">Start time</label>
<div class="col-md-9">
<input type="text" id="starttime" name="starttime" class="form-control" size="30" style="display: none;"><span class="combodate">
<select class="hour " style="width: auto;"><option value="0">00</option><option value="1">01</option><option value="2">02</option><option value="3">03</option><option value="4">04</option><option value="5">05</option><option value="6">06</option><option value="7">07</option><option value="8">08</option><option value="9">09</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option></select> :
<select class="minute " style="width: auto;"><option value="0">00</option><option value="1">01</option><option value="2">02</option><option value="3">03</option><option value="4">04</option><option value="5">05</option><option value="6">06</option><option value="7">07</option><option value="8">08</option><option value="9">09</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option><option value="24">24</option><option value="25">25</option><option value="26">26</option><option value="27">27</option><option value="28">28</option><option value="29">29</option><option value="30">30</option><option value="31">31</option><option value="32">32</option><option value="33">33</option><option value="34">34</option><option value="35">35</option><option value="36">36</option><option value="37">37</option><option value="38">38</option><option value="39">39</option><option value="40">40</option><option value="41">41</option><option value="42">42</option><option value="43">43</option><option value="44">44</option><option value="45">45</option><option value="46">46</option><option value="47">47</option><option value="48">48</option><option value="49">49</option><option value="50">50</option><option value="51">51</option><option value="52">52</option><option value="53">53</option><option value="54">54</option><option value="55">55</option><option value="56">56</option><option value="57">57</option><option value="58">58</option><option value="59">59</option></select></span><span class="combodate"><select class="hour " style="width: auto;"><option value="0">00</option><option value="1">01</option><option value="2">02</option><option value="3">03</option><option value="4">04</option><option value="5">05</option><option value="6">06</option><option value="7">07</option><option value="8">08</option><option value="9">09</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option></select> : <select class="minute " style="width: auto;"><option value="0">00</option><option value="1">01</option><option value="2">02</option><option value="3">03</option><option value="4">04</option><option value="5">05</option><option value="6">06</option><option value="7">07</option><option value="8">08</option><option value="9">09</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option><option value="24">24</option><option value="25">25</option><option value="26">26</option><option value="27">27</option><option value="28">28</option><option value="29">29</option><option value="30">30</option><option value="31">31</option><option value="32">32</option><option value="33">33</option><option value="34">34</option><option value="35">35</option><option value="36">36</option><option value="37">37</option><option value="38">38</option><option value="39">39</option><option value="40">40</option><option value="41">41</option><option value="42">42</option><option value="43">43</option><option value="44">44</option><option value="45">45</option><option value="46">46</option><option value="47">47</option><option value="48">48</option><option value="49">49</option><option value="50">50</option><option value="51">51</option><option value="52">52</option><option value="53">53</option><option value="54">54</option><option value="55">55</option><option value="56">56</option><option value="57">57</option><option value="58">58</option><option value="59">59</option></select></span>
This is what this section of the form looks like (highlighted in red):
ComboBox Form
Here is a snippet of the code I am using:
Sub Legends()
Dim IE As InternetExplorerMedium
Dim Environment As String
Dim webContent As String
Dim NOME_EMPRESA, CNPJ, CPF, COD_ACESSO As String
Dim Lookup_Range As Range
Dim SH
Dim confirmationBox As Integer
confirmationBox = MsgBox("Confirm Legendary Promotion changes to " & Worksheets("Legends").Range("E2") & "?", vbYesNoCancel, "Woolly Legends")
'Confirmation box data if yes is clicked
Select Case confirmationBox
Case vbYes
Dim eachIE
'Choosing the environment
If ThisWorkbook.Sheets("Legends").Range("E2").Value = ThisWorkbook.Sheets("Parameters").Range("A2") Then
AD = ThisWorkbook.Sheets("Parameters").Range("C2").Value
Environment = AD
End If
If ThisWorkbook.Sheets("Legends").Range("E2").Value = ThisWorkbook.Sheets("Parameters").Range("A3") Then
AC= ThisWorkbook.Sheets("Parameters").Range("C3").Value
Environment = AC
End If
If ThisWorkbook.Sheets("Legends").Range("E2").Value = ThisWorkbook.Sheets("Parameters").Range("A4") Then
AB = ThisWorkbook.Sheets("Parameters").Range("C4").Value
Environment = AB
End If
If ThisWorkbook.Sheets("Legends").Range("E2").Value = ThisWorkbook.Sheets("Parameters").Range("A5") Then
Testing = ThisWorkbook.Sheets("Parameters").Range("C5").Value
Environment = Testing
End If
Set IE = New SHDocVw.InternetExplorer
IE.navigate Environment
ShowWindow IE.hwnd, SW_MAXIMIZE
Do
Set SH = New Shell32.Shell
For Each eachIE In SH.Windows
If InStr(1, eachIE.LocationURL, Environment) Then
Set IE = eachIE
'ie.Visible = False 'This is here because in some environments, the new process defaults to Visible.
Exit Do
End If
Next eachIE
Loop
Set eachIE = Nothing
Set SH = Nothing
'Setting doc to allow for form manipulation via Excel
Set doc = IE.document
'Setting the Promotion Names for the Text Promotion
IE.document.all("promo_name").Value = ThisWorkbook.Sheets("Legends").Range("b3")
IE.document.all("race_name").Value = ThisWorkbook.Sheets("Legends").Range("b19")
'Setting start date and end date
IE.document.all("startdate").Value = Format$(ThisWorkbook.Sheets("Legends").Range("b7").Value, "yyyy-mm-dd")
IE.document.all("enddate").Value = Format$(ThisWorkbook.Sheets("Legends").Range("b8").Value, "yyyy-mm-dd")
'Setting the Runner Names
IE.document.all("runner_names_0").Value = ThisWorkbook.Sheets("Legends").Range("b20")
IE.document.all("runner_names_1").Value = ThisWorkbook.Sheets("Legends").Range("b21")
IE.document.all("runner_names_2").Value = ThisWorkbook.Sheets("Legends").Range("b22")
IE.document.all("runner_names_3").Value = ThisWorkbook.Sheets("Legends").Range("b23")
IE.document.all("runner_names_4").Value = ThisWorkbook.Sheets("Legends").Range("b24")
IE.document.all("runner_names_5").Value = ThisWorkbook.Sheets("Legends").Range("b25")
'Setting the dropdown box for the jurisdictions
If ThisWorkbook.Sheets("Legends").Range("B4").Value = "AAA" Or ThisWorkbook.Sheets("Legends").Range("B5").Value = "AAB" Or ThisWorkbook.Sheets("Legends").Range("B6").Value = "AAC" Then
IE.document.all("jurisdiction[]").Options(0).Selected = True
End If
If ThisWorkbook.Sheets("Legends").Range("B4").Value = "BBB" Or ThisWorkbook.Sheets("Legends").Range("B5").Value = "BBA" Or ThisWorkbook.Sheets("Legends").Range("B6").Value = "BBC" Then
IE.document.all("jurisdiction[]").Options(1).Selected = True
End If
If ThisWorkbook.Sheets("Legends").Range("B4").Value = "CCA" Or ThisWorkbook.Sheets("Legends").Range("B5").Value = "CCB" Or ThisWorkbook.Sheets("Legends").Range("B6").Value = "CCC" Then
IE.document.all("jurisdiction[]").Options(2).Selected = True
End If
End Select
End Sub
I am unsure how to pre-populate data from the spreadsheet into the hour and minute comboboxes, as the layout of this is a bit different from the other fields in the html.
Any help or guidance would be greatly appreciated.
Thanks!
The hour and minute boxes are select elements which means with InternetExplorer automation you have two main methods for selecting individual items (and a couple of alternates for tricky situations):
You can use selectedIndex on the select itself then specify index of option of interest in the list under that select. I think starts at 1 but you would need to check.
Use .Selected = True on the option element itself.
As you have options that have the same values you need to isolate the dropdowns by the parent select if using second method. This can be done by adding parent className in front.
Method 1:
hour
ie.document.querySelector(".hour").SelectedIndex = 1
minute
ie.document.querySelector(".minute").SelectedIndex = 1
Method 2:
hour
ie.document.querySelector(".hour [value='0']").Selected = True 'hour 00
minute
ie.document.querySelector(".minute [value='0']").Selected = True 'minute 00
Alternates are predominately the above/variants thereof written in javascript and executed by method of
ie.document.parentWindow.execScript. This can be helpful when elements are not interactable for some reason but generally frowned
upon by QA automation specialists in particular.
Reading:
CSS Selectors
EDIT:
To differentiate starttime from endtime based on html provided e.g.
ie.document.querySelector(".combodate + .combodate .hour [value='0']").Selected =True 'end hour
ie.document.querySelector(".combodate + .combodate .minute [value='0']").Selected =True 'end minute
Using variable
Dim var As Long
var = 0
ie.document.querySelector(".combodate .hour [value='" & cstr(var) & "']").Selected =True 'start hour
Although your HTML doesn't reflect this I would have expected something more like:
ie.document.querySelector("#starttime_field .combodate .hour [value='" & cstr(var) & "']").Selected =True
ie.document.querySelector("#endtime_field .combodate .hour [value='" & cstr(var) & "']").Selected =True
I am having an issue with one part of my automation job, and that is selecting ALL the options in a combobox, on a webpage, using VBA and IE.
This code selects ONE item in the combo box
Set frm = HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
frm.Value = "AUT"
However, when I try to select multiple items, it just selects the last one, not all of them.
Here is the code from the web page
<p id="DispFormCollapsible.Rc10"class="formrow" >
<span id="DispFormCollapsible.Rc10.C1" class="querytextleft">
<label for="UFG.USER_TYPES" id="LabelForContro123"class = "simpletext" >
Accessible Types:<span class="redstar">*</span></label></span>
<span id="DispFormCollapsible.Rc10.C2" class="querytextright">
<span class="labelColumn_combo">
<span class="labelColumn_combi_brdr">
<select name= "UFG.USER_TYPES" multiple= "true" class = "dropdownexpandalbe"
id="UFG.USER_TYPES" title = "Accessible Financial Transaction Types">
<option value="AUT" title="ACTIVE USER TYPE1" >TYPE1</option>
<option value="SET" title="Selective User Type" >TYPE2</option>
<option value="TST" title="Test User Type" >TEST3</option>
</select></span></span>
<input type ="hidden" name= "UFG.USER_TYPES" value="NULL" >
</span></p>
Here is my VBA line to select an item
Set frm = HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
frm.Value = "AUT"
What I need it to do, is select all the "option values" in the combobox. I think it needs to be an array maybe, or some other way. I've tried searching, but I'm getting nowhere. Any help appreciated. Thx
Tried the following, but get an error 91 Block not set. I've also tried using the Values "AUT" in the children, and when doing that I don't get an error, but it doesn not select anything.
With HTMLDoc.getElementsByName("Select")(0)
.Children(1).Selected = True
.Children(2).Selected = True
.Children(3).Selected = True
End With
Also tried the following, this doesn't give an error, but only selects the first option in the list.
With HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
.Children(AUT).Selected = True
.Children(SET).Selected = True
.Children(TST).Selected = True
End With
This is strange, when I use this code, it selects the first two in the list, but not the third.
With HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
.Children(all).Selected = True
End With
With HTMLDoc.getElementsByName("UFG.USER_TYPES")(0)
.Children(0).Selected = True
.Children(1).Selected = True
.Children(2).Selected = True
End With
The above code fixed it... whoopie!
I'm attempting to:
open a specific URL & pass log-in information
grab data from Excel and search specified data
once search is complete, manipulate a data field to correlating Excel data and execute several commands within the application
close IE or loop search for next cell in data
I've attempted using VBA forms and modules.
I found this code online which seemed to have worked once to pass my credentials, but I can't get it to work again.
These Objects all.email & all.password would be found in the source code on the webpage as the ID?
HTMLDoc.all.Email.Value = "email#example.com"
HTMLDoc.all.Password.Value = "ex5566"
Dim HTMLDoc As HTMLDocument
Dim oBrowser As InternetExplorer
Sub Login_2_Website()
Dim oHTML_Element As IHTMLElement
Dim sURL As String
On Error GoTo Err_Clear
sURL = "example.com"
Set oBrowser = New InternetExplorer
oBrowser.Silent = True
oBrowser.timeout = 60
oBrowser.navigate sURL
oBrowser.Visible = True
Do
' Wait till the Browser is loaded
Loop Until oBrowser.readyState = READYSTATE_COMPLETE
Set HTMLDoc = oBrowser.Document
HTMLDoc.all.Email.Value = "email#example.com"
HTMLDoc.all.Password.Value = "ex5566"
For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
If oHTML_Element.Type = "submit" Then oHTML_Element.Click: Exit For
Next
' oBrowser.Refresh ' Refresh If Needed
Err_Clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
End Sub
I think you can use the same code, which you use for finding the submit button, to find the e-mail and password elements. If you know which name or id these elements have (by checking the html code of the page), you can use for instance If oHTML_Element.Name = "password" then oHTML_Element.Value = "ex5566"
If the specific elements have an ID, you can also go directly to them by using oHTML_Element = document.getElementById("[id of element]")
oHTML_Element.Value = "password" This can also be done if they don't have an id, but only a name, but then you have to find out if the name is used multiple times.
The web developer can name their inputs, buttons, forms, ids whatever they want. The email could be named Email, or ID, or Username, or XYZ, this is why you must inspect the elements in the website so you can build your code accordingly. Lets take twitter for example.
<input class="js-username-field email-input js-initial-focus" type="text" name="session[username_or_email]" autocomplete="on" value="" placeholder="Phone, email or username">
The tag is an input tag, with a class name of js-username-field email-input js-initial-focus there is no ID on it, therefore you can not use HTMLDoc.getElementByID, you have to use HTMLDoc.getElementsByClassName or you could use HTMLDoc.getElementsByTagName but if there are more than 1 input you have to loop them and correctly detect the one you need.
Its easier than it sounds but you have to have some basic knowledge of HTML. Continuing with twitter, the tag for the password is:
<input class="js-password-field" type="password" name="session[password]" placeholder="Password">
Different class and different name to differentiate between the two. And finally the login/submit button:
<button type="submit" class="submit EdgeButton EdgeButton--primary EdgeButtom--medium">Log in</button>
With these 3 portions of the HTML elements, you can log in the following way:
HTMLDoc.getElementsByClassName("js-username-field email-input js-initial-focus")(0).Value = "email#example.com"
HTMLDoc.getElementsByClassName("js-password-field")(0).Value = "ex5566"
HTMLDoc.getElementsByClassName("submit EdgeButton EdgeButton--primary EdgeButtom--medium")(0).Click
What does the (0) mean? in HTML you can have many tags with the same class name, and they all are on an array when you call getElementsByClassName, since the login site only has 1 tag with those class names, the array position of "0" is the one you are looking for.
Again, the developer can name the class, the id, anything they want, therefore you want to inspect the website to properly code your script.
I'm trying logging verification, everything seems to be fine, but when I add the special characters string to another variable it causes an error to occur.
I'm trying to detect if a user is inputting special characters such as: !, . etc. something like that.
Here's my code,
<form action="" method="get"/>
username:<input type="text" name="user"/><br>
password:<input type="password" name="pass"/><br>
<input type="submit" value="Login">
</form>
<%
dim user,pass, spchar, getspchar
user=request.querystring("user")
pass=request.querystring("pass")
spchar = "!"
getspchar = spchar
if user = "" then
response.write("Please provide your first name")
elseif pass = "" then
response.write("Please provide your password")
elseif user = spchar or pass = spchar then
response.write(getspchar &" Special character not allowed")
elseif user <> "admin" or pass <> "admin" then
response.write("Invalid Username or Password")
else
response.write("welcome")
end if
%>
What you need to do is check to see if your special characters are in the list. Perhaps something like the following...
<%
Dim user, pass, specchars
'Put all your special characters in the following list...
user = Request.QueryString("user")
pass = Request.QueryString("pass")
specchars = "!£$%^"
If IsValid(user, specchars) And IsValid(pass, specchars) Then
Response.Write("Username and password are fine! Welcome!")
Else
Response.Write("Bad username or password.")
End if
'The reason I've given two arguments here is so that you can have different
'restricted characters for both the username and password...
Function IsValid(phrase, special)
Dim rv, c
For c = 1 to Len(specchars)
rv = (Instr(phrase, Mid(special, c, 1)) = 0)
Next
IsValid = rv
End Function
%>
Just as an aside, here, you're visually displaying your username and password in the query string which is tagged on to the end of your URL (something like www.example.com/default.asp?user=admin&pass=G0d); this isn't a good idea. Try at least using POST in your form instead of GET. If you do this, then you're going to have to look at changing to using Request.Form("controlname") ... and that's just scratching the surface.
Please remember that this is a very basic piece of code and I would not recommend using any structure like this for your security on the internet. You'll need to look into Secure Sockets Layer (SSL) and similar encryption.
<%# language = "VBScript"%>
<!DOCTYPE html>
<html>
<body>
<form method="post" action="">
Username:<br> <input type = "text" name = "user"/><br>
Password:<br> <input type = "password" name = "pass"/><br>
<input type = "submit" name = "register_button" value = "Register"/>
<input type = "submit" name = "submit_button" value = "Submit"/>
</form>
<%
set credentials = Server.CreateObject("Scripting.Dictionary")
set Session("credentials") = credentials
if Request.form("register_button") <> "" then
dim user
dim pass
pass = Request.form("pass")
user = Request.form("user")
Session("credentials").Add user, pass
end if
if Request.form("submit_button") <> "" then
dim userd
dim passd
passd = Request.form("pass")
userd = Request.form("user")
if Session("credentials").Exists(userd) = true then
if Session("credentials").Item(userd) = passd then
Response.Write("ACCESS GRANTED")
else
Response.Write("ACCESS DENIED")
end if
else
Response.Write("USERNAME DOES NOT EXIST")
end if
end if
%>
</body>
</html>
So this is a basic login page I created using Classic ASP. When I type in a user and pass, then click Register, it stores the username and password in the Dictionary no problem. But, when I click the submit button (after filling in the registered credentials), somehow the contents of the dictionary get deleted. So, it fails the "if Session("credentials").Exists(userd) = true then" statement. I even tried making "credentials" a normal variable, without using Session. It still won't work, the dictionary's contents just get deleted. How can I overcome this problem? Thanks in advance!
this first
credentials.Add user, pass
set Session("credentials") = credentials
should be after