Get link from text input field and then open it with DalekJS - automated-tests

I have an issue where the link I need to traverse to using DalekJS that is not clickable, it is rather copy/pastable. How can I retrieve a value from an input field in the browser and then use it in a test.open() call?
<table>
<tbody>
<tr>
<td>Link 1</td>
<td><input type="text" value="http://example.com/link-1" class="start-link"></td>
</tr>
<tr>
<td>Link 2</td>
<td><input type="text" value="http://example.com/link-2" class="start-link"></td>
<tr>
</table>
In the example above I would like DalekJS to dynamically run test.open('http://example.com/link-1'); during the progression of my test.
module.exports = {
'A test case': function (test) {
test.open('http://example.com/example-from-above.html')
.open('http://example.com/link-1') //This is the link I'm trying to retrieve dynamically.
.screenshot('image.png')
.done();
}
}
How can I accomplish this?

DalekJS does not allow reading values of HTML element synchronously and using them in the test scripts. If you need to interact with the content of the testing page, the execute method may help.
You can try setting the window location by a function "executed in the browser":
module.exports = {
'A test case': function (test) {
test.open('http://example.com/example-from-above.html')
// Open the URL from the first input element value
.execute(function () {
var input = document.querySelectorAll('.start-link')[0];
location = input.value;
})
// Wait until the browser opens the page
.waitFor(function () {
return location.pathname.indexOf('link-1') > 0;
})
.screenshot('image.png')
.done();
}
}

Related

How do I change ng-class on window resize?

I have functionality where when I shrink the screen below a certain size and click on a table row it reveals other items in that table row. (white screen on left).
Then when I expand the window I want all table rows to return to normal, but I have a bug where if it's open already it won't close.
I tried setting the $scope.showIt variable to true/false, but it only seems to have an effect if it's the opposite of the initial $scope.showIt value. How do I change all the ng-classes in every td when the screen is a certain size?
This is my html:
<tr class="table-body "ng-repeat="service in services | orderBy:myOrderBy | filter:search">
<td align="center" valign="middle" ng-click="showIt = dropDetails(showIt)" ng-class="{'name-show':showIt, 'name-show-disabled':!showIt}">{{ service.name }}</td>
<td ng-class="{'show':showIt, 'show-disabled':!showIt}">{{ service.description }}</td>
<td ng-class="{'show':showIt, 'show-disabled':!showIt}">{{ service.prices }}</td>
</tr>
And in my controller:
$scope.dropDetails = function(showIt){ //This function works well.
console.log(window)
console.log(window.innerWidth)
if(window.innerWidth < 760){
return !showIt;
}else{
return showIt;
}
}
var w = angular.element($window);
var resizeId=0;
$scope.showIt = true;
w.bind('resize ', function (a) {
clearTimeout(resizeId);
resizeId = setTimeout(function(){
if(w[0].innerWidth < 760){
}else{
$scope.showIt = true; //Does nothing.
$scope.$apply();
}
}, 500);
})
Do use Dot Rule while defining ng-model in Angular view. So that will help you to follow prototypal inheritance while refering to there property.
The reason here is, you have used ng-repeat(which does create prototypically inherited child scope while rendering template each time on view). Here the same thing you need to do. Define model like $scope.model and inside that define showIt property. Rather you should put that showIt on each of you element of services, by which you handle each event individually.
Markup
<tr class="table-body" ng-repeat="service in services | orderBy:myOrderBy | filter:search">
<td align="center" valign="middle"
ng-click="service.showIt= dropDetails(service.showIt)"
ng-class="{'name-show':service.showIt, 'name-show-disabled':!service.showIt}">
{{ service.name }}
</td>
<td ng-class="{'show':service.showIt, 'show-disabled':!service.showIt}">
{{ service.description }}
</td>
<td ng-class="{'show':service.showIt, 'show-disabled':!service.showIt}">
{{ service.prices }}
</td>
</tr>
Now question remains how to hide all the services, so that would be very easy. Loop through each services collection element & make showIt variable as false.
angular.forEach($scope.services, function(service){
service.showIt = false;
})
Also you are using custom event on DOM, I'd suggest you to put this code in directive. So that can get reusable too.

Code still loads content on new page

Hi I have problem with my MVC application.
I would like click on ActionLink > load data from server > and insert data to div in same page.
But my code still loads content on new page and I don`t have idea why. Anybody to help me ?
This is my Index.cshtml in HomeController,
#model IEnumerable<Kango_kmen.KangoKmenWS.WSEntityInfo>
#Content.Script("jquery-1.9.1.min.js", Url)
#Content.Script("jquery.unobtrusive-ajax.min.js",Url)
#Content.Script("jquery.unobtrusive-ajax.js",Url)
#Content.Script("myScript.js",Url)
#section Entities{
<table>
<tr>
<th>
<input type="submit" value="zobrazit" />
</th>
<th>
iD
</th>
<th>
name
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Ajax.ActionLink("..", "CheckEntity", new { id = item.iD },
new AjaxOptions{ UpdateTargetId="properties",
HttpMethod="GET",
InsertionMode=InsertionMode.InsertAfter,
})
</td>
<td>
#Html.DisplayFor(modelItem => item.iD)
</td>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
</tr>
<tr>
<td>
<div id="properties">
</div>
</td>
</tr>
}
</table>
}
#section PropertyInfo{
<p>Property info</p>
}
#section Properties{
<p>properties</p>
}
And here is my Controller in HomeController
public PartialViewResult CheckEntity(int id)
{
var model = WSConnect.getEntityInfo(id);
if(model !=null){
return PartialView("CheckEntity", model.property);
}
var modell = new WSEntityInfo[0];
return PartialView("CheckEntity", modell);
}
and ChecktEntity is the Partial view but everytime I click on ActionLink controller load url: /Home/ChceckEntity/1000 for exmaple on view data on this new page "(
There are 2 things wrong with your code:
You have included the jquery.unobtrusive-ajax.js script twice, once the minified version and once the standard version. You should include it only once
The jquery.unobtrusive-ajax.js is not compatible with jquery 1.9.1 because one of the breaking changes in jQuery 1.9 is that the .live() method was removed and the jquery.unobtrusive-ajax.js script relies on it. If you look at your javascript console you would see the following error: The .live method is undefined.. So if you want to use the unobtrusive AJAX functionality in ASP.NET MVC you will have to downgrade the version of jQuery. For example the 1.8.3 version should be fine.
So:
#model IEnumerable<Kango_kmen.KangoKmenWS.WSEntityInfo>
#Content.Script("jquery-1.8.3.min.js", Url)
#Content.Script("jquery.unobtrusive-ajax.min.js", Url)
#Content.Script("myScript.js", Url)
Also please learn how to debug your javascript code. Use a tool such as FireBug or Chrome developer toolbar where all those errors will be shown.

Problems while Styling a form element that gets data back with ajax

im facing a strange problem while trying to style a form element. A select element in particular.
the idea is simple. i got one select, and when its state changes, through ajax, a second selects gets its data throung a request. so far, everything is ok. the ajax is working fine. but when the first select changes its state, the select element styling is getting back to normal styling.
a live example can be found here
im using 2 main files, the important content of file 1 file is this
<script language="javascript" type="text/javascript">
/* FUNCTION : Ajax Initialize - Start */
function getXMLHTTP() {
var xmlhttp=false;
try{
xmlhttp=new XMLHttpRequest();
}
catch(e) {
try{
xmlhttp= new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e){
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e1){
xmlhttp=false;
}
}
}
return xmlhttp;
}
/* FUNCTION : Ajax Initialize - End */
/* FUNCTION : Get Values - Start */
function getValue(numb) {
var strURL="find.php?theValue="+numb;
var req = getXMLHTTP();
if (req) {
req.onreadystatechange = function() {
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
document.getElementById('my_requestDiv').innerHTML=req.responseText;
} else {
alert("There was a problem while using XMLHTTP:\n" + req.statusText);
}
}
}
req.open("GET", strURL, true);
req.send(null);
}
}
/* FUNCTION : Get Values - End */
</script>
and
<form method="post" action="" name="form1" id="example">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="160" class="title_style">What</td>
<td width="340">
<select class="select" name="start" onChange="getValue(this.value)">
<option value="">please make a selection</option>
<option value="1">Colors</option>
</select>
</td>
</tr>
<tr>
<td width="160" class="title_style">Result</td>
<td width="340">
<div id="my_requestDiv">
<select class="select1" name="my_request" >
<option>Please select above first</option>
</select>
</div>
</td>
</tr>
</table>
</form>
where, after the user makes a selection on select element 1, through ajax, a variable is passed to find.php
<?php
$what=intval($_GET['theValue']);
$link = mysql_connect('localhost', 'YOUR_USERNAME_HERE', 'YOUR_PASSWORD_HERE');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_query("SET NAMES 'utf8'", $link);
mysql_select_db('cry-for-help');
$query="SELECT id, value FROM my_table WHERE requested='$what'";
$result=mysql_query($query);
?>
<select class="select" name="my_request">
<option>make your selection now</option>
<?php
while($row=mysql_fetch_array($result)) {
?>
<option value=<?php echo $row['id']?>><?php echo $row['value']?></option>
<?php
}
?>
</select>
and the result is posted back on file 1 as content for the second select element.
The Problem is that the styling is gone.
you can download the example files here
any help would be appreciated. Also, im sorry if my english is not that good, and my programming skills not that advanced to explain my problem with less words.
Jan
Based on the page to which you linked, it looks the problem is that you are replacing all of the extra HTML elements which have been generated by jqtransform. In your JavaScript callback, you are doing this:
document.getElementById('my_requestDiv').innerHTML=req.responseText;
This replaces the entire contents of the div, blowing away all of the extra elements that jqtransform puts in there. What you actually want to do is replace just the select element itself with the results from your PHP service, or perhaps run jqtransform again after updating the div.
Since you're already including jQuery, I would recommend using their powerful selection functionality to replace just the select element:
$('select[name="my_request"]').replaceWith(req.responseText);
I'm not familiar with the jqtransform library so you may need to investigate further to see which route makes the most sense.

How to Get / Set Div and Table Width / Height

I have a Table (or a region) and want to set it's Width and Height value to another Div (or region).
The second one is actually a Ajax Indicator modal which display a loading text when the page is asynchronously post back. here is the example
<table id="MainTable">
<tr>
<td>
Content ....
</td>
</tr>
</table>
<div id="Progress">
Ajax Indocator
</div>
the following javascript didn't work
document.getElementById("Progress").style.width = document.getElementById("MainTable").style.width;
document.getElementById("Progress").style.height = document.getElementById("MainTable").style.height;
It should work both on IE and FireFox. how to correct it.
I checked some other solution in StackOverFlow but I couldn't fix it.
I'm waiting to hear from you.
Update : I use this
<script>
function SetSize(regionToChange, mainRegion) {
$(document).ready(function() {
$('#regionToChange)
.width($('#mainRegion).outerWidth())
.height($('#mainRegion).outerHeight());
});
}
</script>
and I call it like
<asp:Button ID="btnReset" runat="server" SkinID="Button" Text="Reset" OnClick="btnReset_OnClick" OnClientClick="SetSize('Progress', 'MainTable');" />
But it shows me an error which can not find the object
Update 2 I see this error
and in debugger I face with this
spoken in jQuery:
$(document).ready(function(){
$('#Progress')
.width($('#MainTable').outerWidth())
.height($('#MainTable').outerHeight());
});
in jQuery you can do
$("#Progress").css('width', function(){
return $("#MainTable").width()+'px';
});
and so with the height...
edit
on javascript,
this
document.getElementById("Progress").style.width = document.getElementById("MainTable").style.width;
document.getElementById("Progress").style.height = document.getElementById("MainTable").style.height;
will work if your html is something like this for id="MainTable"
<table id="MainTable" style="width: 500px; height: 300px;">
<tr>
<td>
Content ....
</td>
</tr>
</table>
because you are accessing style attribute...
edit2
function SetSize(regionToChange, mainRegion) {
$(regionToChange)
.width($(mainRegion).outerWidth())
.height($(mainRegion).outerHeight());
}
//you can use it as
SetSize('#Progress','#MainTable'); // prefix '#'if it's an ID

Jquery Functions for operations on gridview with checkboxes

The first column in my gridview (gvAvailable) is a currently checkbox column "chkSelect".
The way it works now is that a user can check multiple checkboxes on a gridview, but I would like a jquery function to deselect all the checkboxes on the gridview except for the checkbox that was clicked.
I was also looking for a way to access the columns of the checked row with jquery on a button click.
Thanks for any help
Here's how the generated html looks
<table class="Grid" cellspacing="0" border="0" id="gvAvailable" style="width:99%;border-collapse:collapse;">
<tr class="GridHeader">
<th scope="col"> </th><th scope="col">Guid</th><th scope="col">Id</th><th scope="col">Name</th>
<th scope="col">Facility</th><th scope="col">Room</th>
</tr>
<tr class="GridItem">
<td>
<input id="gvAvailable_ctl02_chkSelect" type="checkbox" name="gvAvailable$ctl02$chkSelect" />
</td>
<td>24</td>
<td>000101020201</td>
<td>Test</td>
<td>Test Facility</td>
<td> </td>
</tr><tr class="GridAltItem">
<td>
<input id="gvAvailable_ctl03_chkSelect" type="checkbox" name="gvAvailable$ctl03$chkSelect" />
</td>
<td>25</td>
<td>1001</td>
<td>Test 2</td>
<td>Test 3</td>
<td> </td>
</tr>
</table>
if you add the same class to each of the checkboxes in the markup, you can retrieve an array of them by saying
$('.classname')
This will give you back the array of objects. You can then call 'each' on the array and deselect them all.
function removeChecks()
{
$('.classname').each(function()
{
$(this).removeAttr('checked');
});
}
Then add the above function call in the click handler for the each checkbox:
$('.classname').each(function()
{
$(this).click(function()
{
removeChecks();
$(this).attr('checked', 'checked');
});
});
the code above should be set up to run on page load.
In this example I put one button to check, and one button to uncheck gridview checkboxes :
<asp:GridView runat="server" ID="grid"></asp:GridView>
<input type="button" onclick="uncheckCheckBoxes()" value="UnCheck" />
<input type="button" onclick="checkCheckBoxes()" value="Check" />
<script>
function uncheckCheckBoxes()
{
var gridClientID = '<%= grid.ClientID %>';
jQuery.each($("#" + gridClientID + " input[type='checkbox']"), function ()
{
this.checked = false;
});
}
function checkCheckBoxes()
{
var gridClientID = '<%= grid.ClientID %>';
jQuery.each($("#" + gridClientID + " input[type='checkbox']"), function ()
{
this.checked = true;
});
}
</script>
I am assuming you would like to make sure the user clicked checkboxes do not get toggled? If so, go on below.
First, just give a class name to all checkboxes in the gridview.
Whenever a checkbox was clicked, add another class to it to denote it was physically selected.
$('.checkbox').click(function(){
$(this).addClass('checked');
});
Now, when a user clicks on the select all checkbox (let's call it "selectAll") on top, iterate through all the checkboxes and toggle the status while checking the "checked" class
$('#selectAll').click(function(){
var status = $(this).attr('checked')
$('.checkbox').each(function(){
//only toggle if not set
if(!$(this).hasClass('checked')){
if(status){
$(this).attr('checked', 'checked');
}
else{
$(this).attr('checked', '');
}
}
});
});
This should get you along your merry way hopefully.
Now, accessing columns of the checked row?
You could add an onclick event to each table row.
$('#tablename tr').click(function(){
//do something
});
i found this articale very usefull Check/Uncheck all Items in an ASP.NET CheckBox List using jQuery

Resources