Button can't be clicked during automation - protractor

I am trying to click a button which is displayed/visible/present.
When doing it manually, user was able to click the button.
If the test was executed, you will notice that it is trying to click the button, but nothing is happening.
I also tried to put a very long wait and tried to click it manually during automation.
But, when clicking it, nothing also happens.
I cannot share the site since it is in a proxy.
This is the HTML of the button and it looks normal:
<a class="x-btn x-unselectable x-box-item x-toolbar-item x-btn-default-small" style="min-width: 75px; right: auto; left: 328px; top: 0px; margin: 0px;" hidefocus="on" unselectable="on" role="button" aria-hidden="false" aria-disabled="false" id="button-1011" tabindex="-1" data-componentid="button-1011">
<span id="button-1011-btnWrap" data-ref="btnWrap" role="presentation" unselectable="on" style="" class="x-btn-wrap x-btn-wrap-default-small ">
<span id="button-1011-btnEl" data-ref="btnEl" role="presentation" unselectable="on" style="" class="x-btn-button x-btn-button-default-small x-btn-text x-btn-button-center ">
<span id="button-1011-btnIconEl" data-ref="btnIconEl" role="presentation" unselectable="on" class="x-btn-icon-el x-btn-icon-el-default-small " style=""></span>
<span id="button-1011-btnInnerEl" data-ref="btnInnerEl" unselectable="on" class="x-btn-inner x-btn-inner-default-small">Save</span>
</span>
</span>
</a>
Code:
global.elmCBSave = element.all(by.cssContainingText('span', 'Save')).last();
it('should click the Save button.', function() {
global.elmCBSave.click();
});
I also tried using browser.executeSrcipt, this is working when executed thru console:
browser.executeScript('$(".x-btn-inner.x-btn-inner-default-small:eq(3)").click()')

There are a few things you can try.
Be sure to pass done into your callback and handle the returned promise from the click event
it('should click the Save button.', function(done) {
global.elmCBSave.click().then(function(){
done();
});
});
Also, I tend to put an expected condition to wait for element to be clickable: http://www.protractortest.org/#/api?view=ProtractorExpectedConditions.prototype.elementToBeClickable
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to be clickable.
it('should click the Save button.', function(done) {
browser.wait(EC.elementToBeClickable($('#abc')), 5000).then(function(){
global.elmCBSave.click().then(function(){
done();
});
});
});

Related

WebdriverIO can't click on (Ionic) tab

I'm using WebdriverIO to test some basic functionality on an Ionic (+ Angular) application. The framework setup works all right, but I can't find a way to click on certain HTML elements. For instance, this is some HTML sample:
<div class="tabbar show-tabbar" role="tablist" style="top: 166px; display: flex;">
<a class="tab-button has-title has-title-only" href="#" role="tab" id="tab-t0-0" aria-controls="tabpanel-t0-0"
aria-selected="true">
<span class="tab-button-text">Blah</span>
<div class="button-effect"></div>
</a>
<a class="tab-button has-title has-title-only" href="#" role="tab" id="tab-t0-1" aria-controls="tabpanel-t0-1"
aria-selected="false">
<span class="tab-button-text">Foo</span>
<div class="button-effect"
style="transform: translate3d(83px, -103px, 0px) scale(1); height: 240px; width: 240px; opacity: 0; transition: transform 395ms ease 0s, opacity 277ms ease 118ms;"></div>
</a>
<a class="tab-button has-title has-title-only" href="#" role="tab" id="tab-t0-2" aria-controls="tabpanel-t0-2"
aria-selected="false">
<span class="tab-button-text">Bar</span>
<div class="button-effect"
style="transform: translate3d(3px, -99px, 0px) scale(1); height: 240px; width: 240px; opacity: 0; transition: transform 395ms ease 0s, opacity 277ms ease 118ms;"></div>
</a>
<div class="tab-highlight animate" style="transform: translate3d(570px, 0px, 0px) scaleX(285);"></div>
</div>
And this is a super-simple test case that I'm doing to test the functionality:
import { expect } from "chai";
describe("Some Test", () => {
const logingUrl: string = "url0";
const appUrl: string = "url1";
it("Some Test Again", () => {
browser.url(logingUrl);
browser.url(appUrl);
const tab = $("#tab-t0-2");
tab.click();
expect(tab.getAttribute("aria-selected")).to.equal("true");
});
});
..but every time I run it, I get some weird error message that the element is no clickable at some point. Any clues?
[0-0] element click intercepted in "Some Test Again"
element click intercepted: Element <a class="tab-button has-title has-title-only" href="#" role="tab" id="tab-t0-2" aria-controls="tabpanel-t0-2" aria-selected="false">...</a> is not clickable at point (666, 170). Other element would receive the click: <ion-backdrop disable-activated="" role="presentation" tappable="" class="backdrop-no-tappable" style="opacity: 0.5;"></ion-backdrop>
(Session info: headless chrome=75.0.3770.100)
This is one of those classic Angular/Ionic backdrop gotcha's.
Let's start with the error message: element #tab-t0-2 is not clickable at point (coordinates), another element would receive the click: ion-backdrop.
This tells us that your targeted element cannot be clicked as the ion-backdrop tag is rendered on top of it. The ion-backdrop component is a short animation (usually used for modals), in this case, the semi dimming of the background (opacity: 0.5).
✖ Solution 1: Easy way to counter it? Explicitly expect for it to disappear, then click the targeted element.
it("Some Test Again", () => {
browser.url(logingUrl);
browser.url(appUrl);
// Explicitly wait for the backdrop animation to disappear:
const backdrop = $('.backdrop-no-tappable');
backdrop.waitForExist(5000, true, 'Backdrop still present');
const tab = $("#tab-t0-2");
tab.click();
expect(tab.getAttribute("aria-selected")).to.equal("true");
});
✖ Solution 2: Another thing you can try is only click on the tab element, once it is fully visible and intractable in the DOM (this is kind of a best-practice):
const tab = $("#tab-t0-2");
tab.waitForDisplayed(5000);
// For 'wdio-v4' users:
// tab.waitForVisible(5000);
tab.click();
expect(tab.getAttribute("aria-selected")).to.equal("true");

How to trigger mapbox resize on bootstrap-tab click

I have a mapbox map inside a bootstrap-3 tab like so:
<div id='resizeMap' class='button'>Resize map</div>
<div class="tabs">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#tab-87" aria-controls="tab-87" role="tab" data-toggle="tab">
Tab-1
</a>
</li>
<li role="presentation">
<a href="#tab-1034" aria-controls="tab-1034" role="tab" data-toggle="tab">
Tab-2
</a>
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" id="tab-87" class="tab-pane in active fade">
Some other content
</div>
<div role="tabpanel" id="tab-1034" class="tab-pane fade">
<div class="map-container" style="position:relative;width:100%; height:500px;">
</div>
</div>
</div>
The problem is that when I click on the 2nd tab (where the map is, the map does not have the right dimensions).
I can add a button to trigger resize as mentioned here but I can't figure out how to trigger resize automatically upon clicking a tab.
I also tried to "simulate" clicking as in:
$('a[data-toggle="tab"]').on( "click", function() {
$("#resizeMap").click();
});
This works, but only when I click the tab twice: if tab-1 is active, I click tab-2, the tab-content appears with the map not sized correctly, if I click on tab-2 for a second time, it resizes.
Thanks
For anyone else that may face this:
Not having access to the map instance, means that we have to define the call to map.resize() from within map.on('load', function(){...}).
Also, we need to make sure to resize after tab-switching. The following code resizes the map after the bootstrap animation finishes. Like so:
var map = new mapboxgl.Map({
container: 'site-map', // container id
style: 'mapbox://styles/mapbox/outdoors-v10',
center: [1, 49],
zoom: 5,
});
map.on('load', function () {
map.addSource('data',{
type: 'geojson',
data: someData,
cluster:true
})
$('a[data-toggle="tab"]').on('shown.bs.tab', function(){
map.resize();
});
});
If you have access to the map instance (the return value of new mapboxgl.Map()), you can just call the resize method of the the map, after changing tabs: https://www.mapbox.com/mapbox-gl-js/api/#map#resize

how to select toggle on/off button in protractor

I am running E2E on my angular application using Protractor. How to write script for toggle button.
<span class="bootstrap-switch-handle-on bootstrap-switch-primary" style="width: 41px;">ON</span>
<span class="bootstrap-switch-label" style="width: 41px;"> </span>
<span class="bootstrap-switch-handle-off bootstrap-switch-default" style="width: 41px;">OFF</span>
I can't guess the DOM of your page. Firstly, I'd rather not use xpath. IMHO in protractor by should be lowercase.
I assume that after clicking the element class of span changes.
maybe try sth like that:
const button = element(by.css('span.bootstrap-switch-primary'));
button.getAttribute('class').then((classes) => {
if (classes.indexOf('bootstrap-switch-handle-on') === -1) {
return button.click();
}
}

Jquery replace input button onclick event

I have HTML loaded with the Jquery .load method and need to dynamically change anchor HREF and input button ONCLICK targets in this HTML on the client as the page loads, (I don't have the option to change the server generated HTML).
The .load works fine and I can change the HREF target OK but I can't find a way of changing the ONCLICK target?
HTML
Anchor HREF
<div style="width:143px;" id="LM_OBJV">
<span title="View Objectives Detail" class="PSHYPERLINK">
<a class="PSHYPERLINK" href="javascript:Action_win0
(document.win0,'LM_OBJV','Relationship Building',false,true);" tabindex="54"
id="LM_OBJV" name="LM_OBJV">Relationship Building</a>
</span>
</div>
Button ONCLICK
<div id="win0divLM">
<a id="Left" style="background-Color: transparent;border:0;" class="PBUTTON">
<span style="background-Color: transparent;">
<input type="button" onclick="Action_win0(document.win0,'LM_PB', 0, 0, 'Add New',
false, true);" style="width:120px; " class="PBUTTON" value="Add New" tabindex="77"
id="LM_PB" name="LM_PB">
</span>
</a>
</div>
Javascript
$('#result').load('some.php', function() {
$("a.PSHYPERLINK")
.each(function()
{
this.href = this.href.replace("Action_win0", "Action_winx");
});
});
So this JS works fine, loads the HTML into the #results DIV and changes the HREF's from "Action_win0" to "Action_winx".
But how can I also change the input type="button ONCLICK events from "Action_win0" to "Action_winx"? I've tried several Jquery selectors but just can't get it to work :(
$('a.PSHYPERLINK').attr('onclick', 'alert("bar")')
Demo: http://jsfiddle.net/kzVSt/

Jquery Modal Form Input error

Summary: When a dialog window is opened, the dialog contains a form, yet the INPUT fields do not allow text entry. FireBug Console reports the following error when I press a key and the cursor is in the text field:
The 'charCode' property of a keydown event should not be used. The value is meaningless.
/lemonade_stand/start.php Line 0
I also see this error when the window opens:
Unknown pseudo-class or pseudo-element 'tabbable'.
/lemonade_stand/start.php Line 0
It seems that some over event is listening for a keypress. I found an article that suggested that I "remove the ui-dialog class from the div", yet even trying that didn't help.
Code samples:
Definition of Dialog Box
var $priceWindow = $("#setPriceWindow").dialog({
autoOpen: false,
height: 306,
modal: true,
width: 380,
buttons: {
"Save": function(){
$.get('php/saveQA.php',
{
'cup': $("#pCup").val(),
'lemons': $("#pLemons").val(),
'sugar': $("#pSugar").val(),
'ice': $("#pIce").val(),
});
$(this).dialog('close');
},
Cancel: function(){
$(this).dialog('close');
}
}
});
Event to open Dialog box
$("#setPrice").click(function(e){
e.preventDefault();
$priceWindow.dialog('open');
});
PHP/HTML content of dialog
<div id="setPriceWindow" class="priceWin" title="Set Price and Quality">
<form>
<ul>
<li><label>Price Per Cup</label><span><span><input type="text" size="3" id="pCup" tabid="1" value="<?php echo $_SESSION['qa']['cup']; ?>" /><p>Cents</p></span></span></li>
<li><label>Lemons Per Pitcher</label><span><span><input type="text" size="3" id="pLemons" tabid="2" value="<?php echo $_SESSION['qa']['lemons']; ?>" /><p>Lemons</p></span></span></li>
<li><label>Sugar Per Pitcher</label><span><span><input type="text" size="3" id="pSugar" tabid="3" value="<?php echo $_SESSION['qa']['sugar']; ?>" /><p>Cups</p></span></span></li>
<li><label>Ice Per Cup</label><span><span><input type="text" size="3" id="pIce" tabid="4" value="<?php echo $_SESSION['qa']['ice']; ?>" /><p>Cubes</p></span></span></li>
</ul>
</form>
</div>
Full project can be seen here: http://yrmailfrom.me/games/lemonade_stand/start.php
The problem is in your game.js script.
In
$("#setPrice").click(function(e){
e.preventDefault(); **// THIS LINE IS CAUSING THE TROUBLE**
$priceWindow.dialog('open');
});
Also in lemonade_game.css try removing the zIndex from this block
div#setPriceWindow ul li span {
background: none repeat scroll 0 0 #F9F9F9;
border-left: 1px solid #CCCCCC;
border-right: 1px solid #BBBBBB;
margin: 0;
padding: 3px 0;
}