I am a python selenium webdriver newbee.
I am stuck at a dropdown that has an "onchange" parameter in the html.
This is how the inspect window looks:
I am trying to first key in the date to the box called "Start"
Then move on to the dropdown for the "Schools" (School1, School2 etc).
Once I choose the school, the adjacent dropdown (School Levels) will refresh/update/populate with the school levels (middle, high, elem etc) for that school. There is an "onchange=" for this element.
Then move on to the School Levels dropdown to choose the level. There is an "onchange=" for this element, too
And then move on the the grade level dropdown.
I am stuck at the first dropdown.After I enter the start date, it does move on the dropdown and clicks on it and all three schools get visible but the driver does not select the school and does not move on to the adjacent school level dropdown.
As far as I understand from what I have found online, it most probably has to do with the onchange javascript event but couldn't figure out how to fire the event.
Please help.
Thank you in advance.
This is the html block for the start date box:
<div class="inline-block" ><input name="Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$DatePickerStartDate" type="text" size="9" id="Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_DatePickerStartDate" spellcheck="false" style="BACKGROUND:#ff9999;display:inline;" /><input type="image" name="Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$DatePickerStartDate_IB" id="Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_DatePickerStartDate_IB" src="Images/Mindex/WebControls/DatePicker/calendar.jpg" onclick="PopupCal('Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_DatePickerStartDate', 'Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_DatePickerStartDate',false,false); return false;" style="border-width:0px;display:inline;vertical-align:middle;" /></div></nobr>
And this is the html block for the two adjacent dropdowns:
<select name="Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$BuildingDropDown" onchange="javascript:setTimeout('__doPostBack(\'Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$BuildingDropDown\',\'\')', 0)" id="Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_BuildingDropDown">
<option selected="selected" value="3">School1</option>
<option value="4">School2</option>
<option value="5">School3</option>
</select>
<select name="Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$BuildingSchoolLevelDropDown" onchange="javascript:setTimeout('__doPostBack(\'Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$BuildingSchoolLevelDropDown\',\'\')', 0)" id="Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_BuildingSchoolLevelDropDown">
<option selected="selected" value="4">K-8</option>
<option value="5">High School</option>
<option value="6">Summer School</option>
<option value="7">Middle School</option>
<option value="8">Elementary</option>
</select></nobr>
And this is my code:
print("Clicking on student selector icon")
driver.find_element_by_xpath("/html/body/form/div[4]/div[1]/div/div[2]/div/table/tbody/tr/td/table[2]/tbody/tr["+str(r)+"]/td[1]/input").click()
time.sleep(2)
tab_student = driver.find_element_by_id("Template1_Control0_TabHeaderDetails_MenuTabs1_MenuTabStudent")#we can move this to the start of the script
tab_student.click()
time.sleep(3)
icon_add_enrollment = driver.find_element_by_id("Template1_Control0_BottomPanel_IconButtonAdd")#we can move this to the start of the script
icon_add_enrollment.click()
time.sleep(3)
input_startdate = driver.find_element_by_id("Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_DatePickerStartDate")
input_startdate.send_keys("4/21/2010")
time.sleep(2)
print("Start Date entered")
dropdown_school = driver.find_element_by_id("Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_BuildingDropDown")
dropdown_school.select_by_visible_text("School1")
time.sleep(5)
print("School picked")
time.sleep(6)
dropdown_level = driver.find_element_by_id("Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_BuildingSchoolLevelDropDown")
dropdown_level.select_by_visible_text("Elementary")
#or maybe I can use this? actions.move_to_element(dropdown_building).click().perform()
time.sleep(2)
print("Building picked")
time.sleep(6)
dropdown_grade = driver.find_element_by_id("Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_GradeDropDown")
actions.move_to_element(dropdown_grade).click().perform()
time.sleep(2)
dropdown_grade.select_by_visible_text("1").click()
print("Grade picked")
time.sleep(2)
dropdown_ethnicity = driver.find_element_by_id("Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_ddlEthnicity")
actions.move_to_element(dropdown_ethnicity).click().perform()
time.sleep(2)
dropdown_ethnicity.select_by_visible_text("White").click()
print("Ethnicity picked")
time.sleep(2)
icon_save_enrollment = driver.find_element_by_id("Template1_Control0_BottomPanel_StudentEditEnrollmentAdd_IconButtonAdd")#we can move this to the start of the script
icon_save_enrollment.click()
time.sleep(4)
print("Enrollment added.. Moving on to enrolling the next child")
I also tried move_to_element().click(perform() but still not working.
The onchange javascripts in the html is not showing correctly for some reason so I am attaching them below:
//for school dropdown:
javascript:setTimeout('__doPostBack(\'Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$BuildingDropDown\',\'\')', 0)
//for school levels dropdown:
javascript:setTimeout('__doPostBack(\'Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$BuildingSchoolLevelDropDown\',\'\')', 0)
Thank you again.
As far as I understand, this is your exact problem:
After I enter the start date, it does move on the dropdown and clicks on it and all three schools get visible but the driver does not select the school and does not move on to the adjacent school level dropdown.
Which means the error occurs when selecting the dropdowns or <select> inputs once the date is properly detected by the onchange.
Ive found this to work on similar cases:
schoolSelector = Select(driver.find_element_by_xpath('//select[#name="Template1$Control0$BottomPanel$StudentEditEnrollmentAdd$BuildingSchoolLevelDropDown"]'))
schoolOptions = schoolSelector.options
then if you want to iterate through each school you may use schoolOptions to get each one with:
for school in range(0,len(schoolOptions)):
schoolSelector.select_by_index(school)
Edit:
Had not noticed you posted all of your code, I think selecting by index and via XPATH is usually more precise. Give it a shot.
Related
I haven't been able to find anything specific to this case. Im trying to change the displayed html object based on the selection from a drop down menu.
So far I have:
<div class="card-body"></div>
<object id="dategraph" data="assets/img/date_manual_interventions_prefix.html"></object>
<select id="DateGraphList">
<option value="assets/img/date_manual_interventions_prefix.html">
Date Graph - Manual Interventions per 1000Mb - SL
</option>
<option value="assets/img/date_manual_interventions_prefix_v.html">
Date Graph - Manual Interventions per 1000Mb - DL
</option>
<option value="assets/img/date_manual_interventions_prefix_full.html">
Date Graph - Manual Interventions per 1000Mb - FN
</option>
</select>
With the js script for this being:
function setCar() {
var obj = document.getElementById("dategraph");
obj.data = this.value;
return false;
}
document.getElementById("DateGraphList").onchange = setCar;
Could some one point out where i'm going wrong?
Thanks in advance!
Try setting the data attribute of the <object> by using Element.setAttribute.
data
The address of the resource as a valid URL. At least one of data and type must be defined.
Note: Don't forget to set the content type as stated above.
<object
id="dategraph"
type="text/html"
data="assets/img/date_manual_interventions_prefix.html">
</object>
function setCar(e) {
const obj = document.querySelector('#dategraph');
obj.setAttribute('data', e.target.value);
}
document.querySelector('#DateGraphList').addEventListener('change', setCar);
I'm planning to add multiple select field into my project but the problem is I want to capture one more integer value along with every selected value,Can anyone suggest me best way of selecting the value along with multiple select. My multiple select dropdown look like this.. and thanks in advance
<div class=" multiselectdd "><multiselect ng-model="vm.inventory.SiteId" options="site.value as site.label for site in vm.sites" data-header-key="header"data-divider-key="divider" scroll-after-rows="5"filter-after-rows="0">
</div>
I don't get it properly but if you want to select more than one object in your select list you can:
Javascript Side
$scope.SelectedChanged = function (yourModel) {
if (yourModel.length > 1) {
$scope.newModel = yourModel[1];
}
};
HTML Side
<select name="yourElementName" multiple ng-model="yourModel" ng-change="SelectedChanged(yourModel)">
<option value="0">One</option>
<option value="1">Two</option>
<option value="2">Tree</option>
<option value="3">Four</option>
</select>
and call your model to test
<span>{{yourModel}} - Second Value: {{newModel}} </span>
When you select multiple element lets say " One and Two " you will see like:
Output
["0","1"] - Second Value: 1
I have searched to forums over and over again - tried to make sense of some of what people have said, but the solutions never seem to fit my case.
My problem concerns selecting an item from a drop down list that has been coded in AngularJS on a website. I am running automated tests using Protractor and a Selenium server. Right now I am running different scripts I have coded on various websites that have been coded in AngularJS. Its fascinating to see something I code fill out a form automatically - so cool!
Unfortunately whenever I come across a drop down in my test I try and come up with a solution for hours and never have been able to figure it out. So I have come to stack!!
This is the code I am working with it's actually jetblue's sign up website so if you want to take a look go here: https://trueblue.jetblue.com/web/trueblue/register/
The trouble starts on page two with the dropdowns - don't know how to fill out a single one.
Thanks,
FB
<div class="row has-dropdown form-value error" style="z-index: 108; position: relative;"> <label for="my-info-title"> <span aria-hidden="true">*</span> <span class="visuallyHidden">required</span> Title
<div class="tb-select accountData_title"><span class="tb-select-title error">Select</span><div class="tb-select-dropdown"><ul><li class="selected" title=""><span>Select</span></li><li title="DR"><span> Dr
</span></li><li title="JT"><span> Jetter
</span></li><li title="MISS"><span> Miss
</span></li><li title="MR"><span> Mr
</span></li><li title="MRS"><span> Mrs
</span></li><li title="MS"><span> Ms
</span></li></ul></div><select name="accountData_title" class="my-info-title-select" id="my-info-title" style="display: none;"> <option value="">Select</option> <option value="DR"> Dr
</option> <option value="MISS"> Miss
</option> <option value="MR"> Mr
</option> <option value="MRS"> Mrs
</option> <option value="MS"> Ms
title: ElementFinder = $('select#my-info-title');
list: ArrayElementFinder = $('select#my-info-title > option');
First perform the title.click()[This clicks on the title dropdown]. Then choose the title you want to select.
eg: list.get(1).click() which chooses the title as DR
Hope this gives the answer for your problem.
Note: The solution is given with CSS Selectors and typescript.
if the above method fails try the below alternate function.
var selectDropdownbyNum = function ( element, optionNum ) {
if (optionNum){
var options = element.all(by.tagName('option'))
.then(function(options){
options[optionNum].click();
});
}
};
Hope above functions helps you!!
0506
There is one requirement for my application to select multiple items from a listbox in microsoft edge browser
I am using watir webdriver to test my application
The DOM structure is as follows:
<div id="textSearch">
<div id="textSearch">
<select name="#Type" id="textType" onchange="unselectOptionZero('#Type');" size="7" multiple="" width="250">
<option value="*" selected="">- All -</option>
<option value="text1">text1</option>
<option value="text2">text2</option>
<option value="text3">text3</option>
<option value="text4">text4</option>
<option value="text5">text5</option>
</select>
</div>
</div>
I tried these following command to select multiple values
#browser.select_list(:id, "textType").option(:value => "text3").select
#browser.send_keys :control
#browser.select_list(:id, "textType").option(:value => "text4").select
which does not seem to working. I tried using iteration via .select but it does not seem to be working.
I also tried selenium support Selenium::WebDriver::Support::Select.new but it does not help. Is there any other way to select multiple options in microsoft edge browser using execute_script using javascript.
Watir's Select#select selects the options by calling the #click method. Unlike other drivers, Edge treats this like a regular click, which unselects the previous options. This is a known/expected behaviour by the Microsoft Edge Team.
Their suggestion is to use the Actions object to press and hold the control button. However, attempting to do this, ex by calling option.click(:control), will result in an unknown command exception. The Edge driver has not yet implemented the Actions command.
Until then, you will need to execute JavaScript to select the options.
If you are using Watir v6.8 or later, you can use the new #select! method to select the option via JavaScript instead of mouse clicks. This will retain the previously selected values.
s= #browser.select_list(:id, "textType")
s.select!("text3")
s.select!("text4")
Note that #select now supports looking for options by both text and value (as opposed to prior versions where it only checked text).
If you are using earlier versions of Watir, the same can be done using #execute_script:
s= #browser.select_list(:id, "textType")
select_script = 'arguments[0].selected=true;'
#browser.execute_script(select_script, s.option(:value => "text3"))
#browser.execute_script(select_script, s.option(:value => "text4"))
I'm using datatables, with their example i was able to build tables nicely. But the problem is i don't seem to understand how to move the "records per page" element, which is a "span6" class of bootstrap. i do get the point that it's actually javascript which is doing this, need some help on this. Here is the LINK for the example i'm using.
This is the div you are taking about in that page
<div class="span6">
<div id="example_length" class="dataTables_length">
<label>
<select size="1" name="example_length" aria-controls="example">
<option value="10" selected="selected">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>records per page</label>
</div>
</div>
Just copy this to other location and modify the css accordingly.
To modify the DOM using Javascript.
http://woork.blogspot.in/2007/10/how-to-change-text-using-javascript.html
Take a look at this page in their documentation... DataTables dynamic language. It doesn't give the best explanations of how to move things but it's a good place to start experimenting. I was able to hide or change the "records per page" text and I would image there is a way to move it as well.
The preamble on that page says "Changing the language information displayed by DataTables is as simple as passing in a language object to the dataTable constructor. The example above shows a different set of English language definitions to be used, rather than the defaults."
"oLanguage": {
"sLengthMenu": "Display _MENU_ records per page"
}
should give you a place to start.