Finding elements in html pages with dynamic frames - ruby

I am working with a vendor developed web page (SAP BusinessObjects InfoView login page) and am trying to identify and then select a drop-down element on a page. No matter what I try, I get an exception:
require 'watir-webdriver'
ie = Watir::Browser.new
ie.goto "http://svr-boj-bop-01.mgc.mentorg.com:8080/InfoViewApp"
ie.select_list(:id, "authenticationSelectBox").select("secLDAP")
#=> 'error: "unable to locate element, using :id=>"authenticationSelectBox", :tag_name=>"select"....'
I have FireFox and Firebug installed, I can use Firebug to select the element which gives me info about the element. I've tried to specify :id, :name, .div, .browser, .frame, ... nothing changes the error. My suspicion is that the inner frame(s) is creating the page dynamically, based on the select of the "Authentication", but I don't know how to check / validate that is the case.
I've searched and tried most of the suggestions on the site, nothing is helping.
The page has lots of Java code, forms, etc. Here is a snip from the page I'm trying to search for elements:
<body onload="logonPageLoad()">
<div class="logonContainer">
<div class="logonIFrame">
<iframe id="infoView_home" width="80%" frameborder="0" align="center" title="Log On to InfoView" name="infoView_home" onload="resizeFrameToContent("infoView_home")" src="jsp/listing/blank.jsp" style="height: 287px;">
<html class="logon_body">
<body class="logon_body" onload="loadInit();">
<div class="logon_body">
<div id="logonCredentials">
<form action="../../../PartnerPlatformService/service/app/logon.object" method="POST" name="logonForm">
<div class="logon_table">
<div id="authentication" class="logon_input">
<label class="logon_input_label" onclick="businessobjects.webutil.accessibility.setFocusOnElement('authenticationSelectBox'); return false;" tabindex="-1" for="authenticationSelectBox"> Authentication: < /label>
<select id="authenticationSelectBox" class="logonSelectBox" onchange="SetAuthType(false);resizeFrameToContent('infoView_home')" name="authType">
<option value="secEnterprise" selected=""> Enterprise `</option>
<option value="secLDAP"> LDAP </option>
<option value="secWinAD"> Windows AD </option>
<option value="secSAPR3"> SAP</option>
</select>

For elements in frames, you have to explicitly call out the frame:
my_frame = ie.frame(:id, "infoView_home")
my_frame.select_list(:id, "authenticationSelectBox").select("secLDAP")
Though it sounds like you might have already tried that. It is possible, that the element is not being loaded before Watir thinks the page is loaded. If that's the case, you can add a wait using something like the when_present method.
my_frame = ie.frame(:id, "infoView_home")
my_frame.select_list(:id, "authenticationSelectBox").when_present.select("secLDAP")
Note that you can do it in one line (ie you do not need the my_frame). It is just added to make it easier to read (ie minimize horizontal scrolling).

Related

Thymeaf Calculated URL Value

I need to get a value from the select component of my page and set its value as a parameter in the href.
<td class="body-item mbr-fonts-style display-7"><a th:href="#{/export(exportEntity='Person',semester='javascript:document.getElementById(\'semester\').value')}">Download</a></td>
Semeter variable has the value at my server side:
semester = javascript:document.getElementById('semester').value
and not the dropdown value.
Unfortunately, this code is not picking the value from the select component. Any guess what I have done wrong here.
Thymeleaf runs on the server, while JavaScript runs on the browser. You can't mix it like that.
It's difficult to say what to do, because your question is lacking context, specifically: What is the element with the id semester?
If it's a select element (or another form element), then it would be possible to use neither Thymeleaf nor JavaScript, but a simple form:
<form method="get" action="/export">
<input type="hidden" name="exportEntity" value="Person">
<select name="semester">
<option value="A">Semester A</option>
<option value="B">Semester B</option>
</select>
<input type="submit" value="Download">
</form>
Clicking on the button will have the browser generate an URL such as /export?exportEntity=Person&semester=A and go to it.

Capybara Datalist Select not visible

I have the following HTML snippet:
<input type="text" id="manufacturer" list="manufacturers" placeholder="Search by manufacturer name or supplier code" class="form-control form-control-2-3" value="" name="manufacturer">
<datalist id="manufacturers">
<select>
<div>
<option value="Jaguar">AA</option>
<div></div>
</div>
<div>
<option value="Audi">AB</option>
<div></div>
</div>
<div>
<option value="Mercedes">AC</option>
<div></div>
</div>
</select>
</datalist>
It's a dropdown menu and I want to select one of the options. No matter what I try with any find command or select function. I always get the same error:
Selenium::WebDriver::Error::ElementNotVisibleError: element not visible: Element is not currently visible and may not be manipulated
Does anyone have any suggestions on how to scope to those options and select one?
Thanks.
What you're trying to do isn't currently possible because it's not actually a dropdown select element. The <datalist> option elements are never actually visible on the page because the standard states "In the rendering, the datalist element represents nothing and it, along with its children, should be hidden." - https://html.spec.whatwg.org/dev/form-elements.html#the-datalist-element . Instead any <option> elements in the datalist are just used as autofill suggestions for the input element (but don't actually restrict the value a user can input in any way). Because of this and since the datalist user can just type anything they want into the input element you can set the input value like any other text input.
fill_in("manufacturer", with: 'Jaguar')

ElementNotVisibleError - A Specific Watir-Webdriver Issue

Trying to do
b.select_list(:name => "bedroomsMin").select '3+ Beds'
on
<div class="beds col-sm-2 hidden-xs">
<div class="form-group">
<select class="form-control wide" name="bedroomsMin">
<option value="null">All Beds</option>
<option value="0">0+ Beds</option>
<option value="1">1+ Beds</option>
<option value="2">2+ Beds</option>
<option value="3">3+ Beds</option>
<option value="4">4+ Beds</option>
<option value="5">5+ Beds</option>
</select>
</div>
</div>
but get the following error:
element not visible: Element is not currently visible and may not be manipulated (Selenium::WebDriver::Error::ElementNotVisibleError).
This list selector is contained in a dropdown element that is clicked like this:
b.link(:class => 'btn-open-filers').when_present.click
How can I select if it's not visible? Is there a way to force visibility?
Sounds like a timing issue. When the link is clicked, the dialog containing the select list may not appear before Watir tries to interact with it.
Try waiting for the select list:
b.select_list(:name => "bedroomsMin").when_present.select '3+ Beds'
Looks like the <div class="beds col-sm-2 hidden-xs"> having hidden may have something to do with it.
Also it appears you're are only checking for when the element is present, which is to say if it loads in the html but is not visible it'll still return true.
Here's a quick read on that:
What's the difference between `visible?` and `present?`?
Since you have it clicking the dropdown after it checks for it's presence, there might be a timing issue. In which case it may check that the dropdown is present in the DOM but is not actually opening the dropdown.
May want to try something like:
dropdown = b.link(:class => 'btn-open-filers')
dropdown.click if dropdown.visible?
b.select_list(:name => "bedroomsMin").select '3+ Beds'
Watir is designed to interact with the elements that a user can interact with. So if it isn't visible to a user, you shouldn't be able to interact with it. So, it's feature, not a bug. :)
That being said, it isn't clear from your post what action is causing the error. This code will wait for the select list to become visible before you try to select an option inside it:
b.link(class: 'btn-open-filers').when_present.click
b.div(class: 'form-group').wait_until_present
b.select_list(name: 'bedroomsMin").select '3+ Beds'
Justin's answer is functionally the same as this, and when_present is probably more elegant.

Dropdown list not working fine in IE10

When i am clicking on my dropdown list, all the values are coming fine in all the older versions of IE but not in IE10. After I am selecting a particular value, next time when i am clicking on my dropdown, the values before the selected values are displayed above the dropdown area.
Example, if I have 4 values in my dropdown, after selecting 3rd value from the dropdown, next time when I am clicking on it to change the value, list dropdown is opening vertically upwards from 3rd otion, instead of downwards.
I tried to add meta tags as well.
I know that this is the default behaviour of IE 10 but want to know how to override it to make it look as in older versions of IE. Checked in other forums, no proper solution is given.
Please help. Here's the sample code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">
</head>
<body>
<p id="demo"> Please enter your name </p>
Name: <input type="text" id="fname"> <br>
<label>Cars:</label>
<select id= "cars">
<option value=""></option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
</body>
</html>

angularjs $scope.$apply() doesnt update select list on ajax IE9

So to keep it simple, im trying to update my select list with a new list of items that i get from an ajax-call. The list has the items. I set the model to the new list and do a $scope.$apply(). This works great in firefox, but not in IE. What am I doing wrong? Is there some IE9-thing that I'm missing? (I've been looking for a few hours now and am ready to give up). Appreciate all the help I can get.
HTML:
<select
ng-model="SelectedParameter"
ng-options="Parameter.Name for Parameter in AllParameters">
</select>
JS:
$.getJSON("/Cont/GetList", {id: id},
function (result) {
var allParameters = result.Data.AllParameters;
$scope.AllParameters = allParameters;
$scope.$apply();
}
);
You'd be way better off doing this the "Angular way". No JQuery required! In fact, if you find yourself doing things the "JQuery way" you're probably doing it wrong. Mark Rajcok had a really good question (and answer) about this same thing on StackOverflow a while ago:
app.js
//declare your application module.
var app = angular.module('myApp', []);
//declare a controller
app.controller('MainCtrl', function($scope, $http) {
//function to update the list
$scope.updateList = function () {
$http.get('/Cont/GetList', function(data) {
$scope.allParameters = data;
});
};
//initial load
$scope.updateList();
});
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="angular.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="MainCtrl">
<button ng-click="updateList()">Update</button>
<ul>
<li ng-repeat="parameter in allParameters">{{parameter | json}}</li>
</ul>
<!-- EDIT: Because you requested a select.
or if you wanted to do a select list
assuming every object in your array had a "name" property
you wanted to display in the option text, you could do
something like the following:
(NOTE: ng-model is required for ng-options to work)
-->
<select ng-model="selectedValue" ng-options="p as p.name for p in allParameters"></select>
<!-- this is just to display the value you've selected -->
<p>Selected:</p>
<pre>{{selectedValue | json}}</pre>
</div>
</body>
</html>
EDIT: A common problem in IE
So first of all, if you're having a problem in IE, I'd recommend hitting F12 and seeing what errors you're getting in the console.
The most common issue I've seen that breaks things in IE relate to commands such as console.log() which don't exist in IE. If that's the case, you'll need to create a stub, like so:
//stub in console.log for IE.
console = console || {};
console.log = console.log || function () {};
I think it's an IE issue. Try setting display:none before you update, then remove the display setting after you update.
I believe it is this bug that is ultimately the problem. I've been pulling my hair out for a couple of days on something very similar, a select filtered off of another.
At the end of the day OPTIONS are being added dynamically and IE9 just chokes on it.
<div class="col-lg-2">
<div class="form-group">
<label>State</label>
<select data-ng-model="orderFilter.selectedState"
data-ng-options="s.StateAbbr for s in states"
data-placeholder="choose a state…"
class="form-control">
<option value=""></option>
</select>
</div>
</div>
<div class="col-lg-2">
<div class="form-group">
<label>County</label>
<select data-ng-model="orderFilter.selectedCounty"
data-ng-options="c.CountyName for c in filteredCounties | orderBy:'CountyName'"
data-ng-disabled="orderFilter.selectedState == null"
data-placeholder="Choose a county…"
class="form-control">
<option value=""></option>
</select>
</div>
</div>
Regards,
Stephen

Resources