Protractor and jasmine: with firefox, I can´t click on button because another element obscures it - jasmine

I can´t click on button:
// tslint:disable-next-line:no-shadowed-variable
elementToClick.isEnabled().then(function(isEnabled) {
if (isEnabled) {
console.log('button enabled');
browser.
wait(protractor.ExpectedConditions.elementToBeClickable(elementToClick), 50000)
.then(function() {
elementToClick.click();
});
}
});
Click fails due:
Failed: Element is not clickable at point (1781.908317565918,887) because another element obscures it
Do you know why?
The class modal fade show d-block is on top of button div.

Related

Screenshot in Cypress happens too soon

For some reason Cypress is not taking a screenshot after the new page loads after clicking on menu item inside of dropdown menu.
it.only('2.4 - Press "My Settings" on the top right corner - "My Settings" screen is displayed.', () => {
cy.login()
cy.get('body div button[data-cy=usermenubutton]')
.click()
.get('body div ul li[data-my=mySettings]')
.contains('My Settings')
.click()
.screenshot()
})
It runs correctly, I can see it click on My Settings and that new page loads up, but it has already taken the screenshot by then. What is happening here? Keep in mind I am brand new to Cypress.
I tried doing the following:
it.only('2.4 - Press "My Settings" on the top right corner - "My Settings" screen is displayed.', () => {
cy.login()
cy.get('body div button[data-cy=usermenubutton]')
.click()
.get('body div ul li[data-my=mySettings]')
.contains('My Settings')
.click()
cy.get('[data-cy=headerTitle]')
.should('be.visible')
.screenshot()
})
When I do it this way I get an error:
expected '<vid.sc-gsDKAQ.eaXakP.MuiBox-root>' to be 'visible'
This element <vid.sc-gsDKAQ.eaXakP.MuiBox-root> is not visible because it has CSS property: position: fixed and it's being covered by another element:
When I try doing it this way:
cy.get('[data-cy=headerTitle]')
.should('be.visible')
.screenshot()
I get a poor screenshot, it's just the area of the new page and not the whole page, no heard, no sidebar and so on.
You should wait for the page you want to take a screenshot of to load. To do so, add a assertion to check if the "My Settings" screen has properly loaded before you call screenshot(). I usually check for an element that should only be visible in the target page to actually be visible before firing my screenshot:
it.only('2.4 - Press "My Settings" on the top right corner - "My Settings" screen is displayed.', () => {
cy.login()
cy.get('body div button[data-cy=usermenubutton]')
.click()
.get('body div ul li[data-my=mySettings]')
.contains('My Settings')
.click()
cy.get('selector_of_an_element_only_visible_in_My_Settings')
.should('be.visible')
.screenshot()
})
As stated in the docs here, should(), like other cy commands, will continue to retry its assertion until it passes or until it times out.
If you're confident on the element you're asserting on and the screenshot still happens too fast, you should consider using cy.wait() and pause the test for 1 second.
cy.get('[data-cy=headerTitle]')
.should('be.visible')
.wait(1000)
.screenshot()

React-boostrap popover dismissal on content hover

I have OverlayTrigger with trigger='hover'. Expected behaviour here would be hiding popover when I moved cursor out of it. However, library hides popover when I move cursor out of button, i.e.
<OverlayTrigger trigger='hover' placement='left' overlay={
<Popover>
... content ...
</Popover>
}>
<Button bsStyle='default'>name</Button>
</OverlayTrigger>
So, when cursor out of button on popover content (if I want to click on link there for instance) it disappears.
Any solutions for this?
I am just starting to learn React. My solution to this is to set trigger option as "manual", and add onMouseOver={fn} and onMouseOut={fn} to manually show and hide the PopOver content. Here is my sample code:
var popOver_timer;
var Pop = React.createClass({
mixins: [TimerMixin],
mouseOverhandler: function() {
this.clearTimeout(popOver_timer);
this.refs.pop.show();
},
mouseOuthandler: function() {
popOver_timer = this.setTimeout(
()=> {this.refs.pop.hide();},
50
);
},
render: function() {
return (
<div onMouseOver={this.mouseOverhandler} onMouseOut={this.mouseOuthandler}>
<OverlayTrigger ref="pop" placement="bottom" trigger="manual" container={document.body} overlay={
<Popover onMouseOver={this.mouseOverhandler} onMouseOut={this.mouseOuthandler}>
This Page
</Popover>}>
<a href={this.props.popUsrUrl}>
<button>PopOver</button>
</a>
</OverlayTrigger>
</div>
);
}
});
Besides react-boostrap, I also require react-time-mixin and use the react-setTimeout. It is because when your mouse moves from the button to the popover content, the onMouseOut will be triggered first, then the onMouseOver. Therefore, a time delay for onMouseOut should be set. I set it to 50 ms. Hope it helps.

Bootstrap Popover Keep HTML

How to save popover contents upon re-initializing? Here is my code and the popup contains a form. I want to keep the form values if user comes back to after filling some info...
$(this).popover({
html: true,
trigger: 'manual',
placement: 'bottom',
content: function () {
var $contents = $('#popover_template').html();
return $contents;
}
}).popover('toggle');
I don't want any modal window etc. Is there a way to keep the contents of a form even if the popover is reopen.
Thanks.
You can use the "hidden" event to detect when your popover closes, then set its content back to your #popover_template div.
$(this).popover({
// your initialization code
}).popover('toggle')
.on("hidden", function(e) {
$('#popover_template').html($(this).html());
});
References
How to attach a function to popover dismiss event (Twitter Bootstrap)
Bootstrap modal popover hide on close
Bootstrap Popover - Save HTML on close

How Do I Reselect A KendoUI TabStrip After AJAX Postback in UpdatePanel

Setup
I've got a Telerik Kendo UI TabStrip with multiple tabs inside of an UpdatePanel...
<asp:UpdatePanel ID="DataDetails_Panel" UpdateMode="Conditional" runat="server">
<div id="ABIOptions_TabContainer">
<ul>
<li>Attendance</li>
<li>Grades</li>
<li>Gradebook</li>
<li>PFT</li>
<li>Scheduling</li>
<li>Miscellaneous</li>
<li>Parent Data Changing</li>
</ul>
</div>
</asp:UpdatePanel>
...which I then wire up in javascript later...
var optionTabContainer = $("#ABIOptions_TabContainer").kendoTabStrip({
animation: {
open: {
effects: "fadeIn"
}
},
select: onMainTabSelect
}).data("kendoTabStrip");
Scenario
The users will click on the various tabs and inside of each tab are settings for our portal. When they are in a tab and they make a change to a setting, the expectation is that they'll click on the 'Save' button, which will perform a postback to the server via ajax, because it is in the update panel.
Current Behavior
After the post back happens and the ul content comes back, I reapply the kendoTabStrip setup function call, which makes none of the tabs selected. This appears to the user like the page is now empty, when it just had content.
Desired Result
What I want to do, is after the partial postback happens and the UpdatePanel sends back the ul, I want to reselect the tab that the user previously selected.
What Already Works
I already have a way to preserve the tab that the user clicked on:
var onMainTabSelect = function (e) {
tabToSelect = e.item;
console.log("onTabSelect --> ", e.item.textContent);
}
and a function to reset the selected tab whenever it is called:
function setMainTab() {
if (!jQuery.isEmptyObject(tabToSelect)) {
var tabStrip = $('#ABIOptions_TabContainer').data("kendoTabStrip");
console.log("Attempt to set tab to ", tabToSelect.textContent);
tabStrip.select(tabToSelect);
} else {
console.log("tabToSelect was empty");
}
}
What Doesn't Work
My hypothesis is that the Kendo TabStrip says, "Hey, that tab is already selected" when I call the setMainTab after my postback:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
BindControlEvents();
setMainTab();
});
...and therefore, doesn't set my tab back. If I click on the tab, then Poof, all my content is there just like I expect.
Any ideas what I may be doing wrong?
I ended up changing the onMainTabSelect method to:
var onMainTabSelect = function (e) {
tabToSelect = $(e.item).data("tabindex");
}
which gets me the data-tabindex value for each li in my ul. I couldn't get the tab index from kendo, so I had to role my own. Once I got that value, then I was able to set the selected tab via an index rather than the tab object reference itself.

DOM element reappearing after empty() called

I have a button which when clicked the first time it will load another html page.
When it is clicked the second time it will empty a div of the loaded page.
However, for some reason the loaded content keeps reappearing after the second click....
CSS:
#boatdiv {
width: 100%;
}
.clicked {}
HTML
<button id="load"></button>
<div id="boatdiv"></div>
jQuery
$(document).ready(function() {
$.ajaxSetup ({
cache: false
});
var loadURL = "AjaxLoad_injection.html";
$("#load").on("click", function() {
if(!($(this).hasClass("clicked"))){ //checks if button has NOT been clicked
$("#boatdiv").html("<p>loading...</p>").load(loadURL);
}
else {
$("#boatdiv").empty();
}
$("#boatdiv").toggleClass("clicked");
}
);
}); // end ready
What's going on?
You test $(#load) but toggle $("boatdiv").
Try :
$("#load").on("click", function() {
if(!($(this).hasClass("clicked"))){ //checks if button has NOT been clicked
$("#boatdiv").html("<p>loading...</p>").load(loadURL);
}
else {
$("#boatdiv").empty();
}
$(this).toggleClass("clicked");
});
You are toggling class on wrong element. You want it to toggle on the element being clicked. Same as code I gave you in last post.
Simple to walk through it, you are testing this... so need to toglle the class on this
Use
$(this).togglClass('clicked')
Remember that ajax calls are asynchronous. You may be clicking the button a second time before the ajax call has returned.
You could disable the button during the ajax call, like this:
$('#load').on('click', function() {
if (!$(this).hasClass("clicked")) {
$('#load').attr('disabled', true);
$("#boatdiv").html("<p>loading...</p>").load(loadURL, function() {
$('#load').attr('disabled', false);
});
} else {
$('#boatdiv').empty();
}
//$('#boatdiv').toggleClass("clicked");
$('#load').toggleClass("clicked");
});
The button is disabled before the ajax call. A callback function is passed as a second parameter to the "load()" function. It will be called when the ajax call returns. It will re-enable the button.
EDIT: I missed that the wrong element was getting the class toggled, but I still think you want to disable the button during the ajax call or things can get messed up.

Resources