How to test 'HOVER' using Cypress(.trigger('mouseover') doesn't work) - javascript

I wonder if it's possible to test coverable dropdown menu bar using Cypress.
For example, when you go to Ebay(https://www.ebay.com), you'll see the alert icon at the top-right corner of the page and if you hover on that element, sign-in notification box will show up.
Here is my code and I followed what Cypress told me to do but I got an error like...
AssertionError
Timed out retrying: Expected to find element: #ghn-err, but never found it.
it('ebay hover test', () => {
cy.visit('https://www.ebay.com')
// 1. alert icon hover test.
cy.get('#gh-Alerts-i').trigger('mouseover')
cy.get('#ghn-err').should('be.visible')
// 2. This is my another test.
// cy.get('#gh-eb-My > .gh-menu > .gh-eb-li-a > .gh-sprRetina').trigger('mouseover')
//cy.get('#gh-eb-My-o > .gh-eb-oa thrd').should('be.visible')
})

For me mouseover works. It's a known Cypress bug pending to be solved.
However, try these:
cy.get('#gh-Alerts-i').trigger('onmouseover')
cy.get('#gh-Alerts-i').trigger('mouseenter')
cy.get('#gh-Alerts-i').invoke('trigger', 'contextmenu')
cy.get('#gh-Alerts-i').rightclick();

I had the same problem, I finally found this plugin that does exactly what I was looking for: do real events instead of simulated ones (simulated == launched with javascript).
https://github.com/dmtrKovalenko/cypress-real-events#cyrealhover
Just install it, add a line to cypress/support/index.js file (do not forget! See 'install' paragraph at the top of the page) and use cy.get(<element>).realHover().

If .trigger() does not work for you, it could also be that your display logic is controlled via CSS instead (for example with .class:hover). You could then rework the display logic to toggle a class with mouseenter and mouseleave events instead.

Related

Python Selenium button isn't being clicked

I am trying to scrape data from this website (https://www.ilcollege2career.com/#/) using python (selenium and beautiful soup).
The code I have is this:
driver = webdriver.Chrome('my file path')
driver.get('https://www.ilcollege2career.com/#/')
first_click = WebDriverWait(driver,5).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="tutorial-modal"]/div/div/div/div[3]/button[1]')))
first_click.click()
second_click = WebDriverWait(driver,5).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="tutorial-start-modal"]/div/div/div[2]/div[2]')))
second_click.click()
So my problem is that while the first click works and it goes to the tutorial step the second click which will close the tutorial doesn't click. For some reason time.sleep() works but I don't want to have to keep repeating that every step. Am I doing something wrong?
I have also tried find element by css as well.
Thank you.
The xpath to the second_click is not accurate in the sense that it does not send the click to correct element. try this out,
driver.fullscreen_window()
driver.get('https://www.ilcollege2career.com/#/')
first_click = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="tutorial-modal"]/div/div/div/div[3]/button[1]')))
first_click.click()
Option#1 -
second_click = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH, "//button[#onclick='closeTutorial()']")))
second_click.click()
Option#2 -
second_click = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH, "//div[#onclick='closeTutorial()']")))
second_click.click()
I found the solution to those who are looking for it.
invisible = WebDriverWait(driver, 10).until(EC.invisibility_of_element_located((By.ID, 'tutorial-modal')))
if invisible:
There was something running behind that wouldn't close out so I was never able to close that and by doing this I was able to exit out.

get the style of the marker I clicked on in mapbox

I'm trying to get the style of the icon which I clicked on, in order to get its translate values.
I'm doing this because I want to create a div that will have the same location on the map as the icon who got clicked on.
this is my website so far:
http://www.david-halfon.com/radio/index.html
Basically, each time someone presses the yellow circle, a div should appear around it.
this is the code for events that happen when an icon is being clicked:
locale.on('click', function(e) {
$("#music").attr("src", prop.Url);
$(".player").show();
play();
sendWithAjax(prop.Country, prop.City);
$("h1").html(prop.Station);
$("h2").html(prop.Country);
$("h3").html(prop.City);
//console.log($(this).css("transform"));
//console.log($(this).attr("style"));
console.log($(this));
setTimeout(function(){ $("h4").html(globalVar);}, 500);
$(".plusB").show();
$(".shareB").show();
map1.setView(locale.getLatLng(), 4);
playNow = prop.Station;
playNowCountry = prop.Country
playNowCity = prop.City;
});
The comments are what I have tried to do so far but it does'nt seems to work.
When I'm trying to consloe.log(this) I get 'undefined'.
Thank you!!
The reason why you don't get the expected $(this).css(...) informations is that this is not a regular DOM object, as it clearly appears using Firebug:
The <img> you want to get style from is contained in the _icon member of this object, so you can use e.g.:
console.log($(this._icon).css('transform'));
console.log($(this._icon).attr('style'));
// and so on
This way (tested using Firebug on your website), it works fine.
BTW, I couldn't figure out why the click event targets this object rather than the <img>...
BTW again, this website is a great idea: cool!

Is protractor.findElement() meant to scroll to that element?

My current unit test (protractor + angularJS project) is failing with the error UnknownError: unknown error: Element is not clickable at point (525, 1103). I used debugger to stop it just before failure, and the only reason I can think that it would fail is because the button is not in the view port (you would have to scroll down).
The failing lines are
homeLink = ptor.findElement(protractor.By.linkText('Home'));
homeLink.click();
expect(ptor.getCurrentUrl()).toBe(homeUrl);
From https://github.com/angular/protractor/issues/319, he says '...when i use findElement() it will scroll them to the "top" of the page'. And the comments agree.
In my test homeLink = ptor.findElement(protractor.By.linkText('Home')); is not causing the the page to scroll.
Am I wrong in thinking it should?
What should I be doing?
You need to scroll down (or maximize browser if this allows you to see the button you would like to click on) first so that the button is visible on the page:
var scrollIntoView = function () {
arguments[0].scrollIntoView();
}
browser.executeScript(scrollIntoView, yourwebelement);
don't forget to get the webElement browser.driver.executeScript("arguments[0].scrollIntoView(true);", ed.getWebElement());

Cycle2 - goto: skipping

Is there a way in Cycle2 to tell when the goto function is being skipped due to it already being on that slide.
I have some cases where it could handle and I want to handle this in a proper way, but I can't seem to find any event that's being triggered for this.
$slider.cycle('goto', 0); //[cycle2] goto: skipping, already on slide 0
The code for goto doesn't fire if you are targeting the current slide. You can see this in the source code (line 951 as of this writing):
if (num == opts.currSlide) {
opts.API.log('goto: skipping, already on slide', num);
return;
}
If the license allows it, remove that block from the code and handle the cycle-before event that will now be fired (I didn't test it, but I assume it will!). You could also directly implement your logic there or even add a custom event yourself, depending on what you are planning to do.

How can I reveal content and maintain its visibility when mousing to a child element?

I'm asking a question very similar to this one—dare I say identical?
An example is currently in the bottom navigation on this page.
I'm looking to display the name and link of the next and previous page when a user hovers over their respective icons. I'm pretty sure my solution will entail binding or timers, neither of which I'm seeming to understand very well at the moment.
Currently, I have:
$(document).ready(function() {
var dropdown = $('span.hide_me');
var navigator = $('a.paginate_link');
dropdown.hide();
$(navigator).hover(function(){
$(this).siblings(dropdown).fadeIn();
}, function(){
setTimeout(function(){
dropdown.fadeOut();
}, 3000);
});
});
with its respective HTML (some ExpressionEngine code included—apologies):
<p class="older_entry">Older<span class="hide_me">Older entry:
<br />
{title}</span></p>
{/exp:weblog:next_entry}
<p class="blog_home">Blog Main<span class="hide_me">Back to the blog</span></p>
{exp:weblog:prev_entry weblog="blog"}
<p class="newer_entry">Newer<span class="hide_me">Newer entry:
<br />
{title}</span></p>
This is behaving pretty strangely at the moment. Sometimes it waits three seconds, sometimes it waits one second, sometimes it doesn't fade out altogether.
Essentially, I'm looking to fade in 'span.hide_me' on hover of the icons ('a.paginate_link'), and I'd like it to remain visible when users mouse over the span.
Think anyone could help walk me through this process and understand exactly how the timers and clearing of the timers is working?
Thanks so much, Stack Overflow. You guys have been incredible as I walk down this road of learning to make the internet.
If you just want to get it working, you can try to use a tooltip plugin like this one.
If you want to understand how this should be done: first, get rid of the timeout, and make it work without it. The difference (from the user's point of view) is very small, and it simplifies stuff (developing and debugging). After you get it working like you want, put the timeout back in.
Now, the problem is you don't really want to hide the shown element on the navigator mouse-out event. You want to hide it in its own mouse out event. So I think you can just pass the first argument to the navigator hover function, and add another hover to dropdowns, that will have an empty function as a first argument, and the hiding code in its second argument.
EDIT (according to your response to stefpet's answer)
I understand that you DO want the dropdown to disappear if the mouse moves out of the navigator, UNLESS its moved to the dropdown itself. This complicates a little, but here is how it can be done: on both types of items mouse-out event, you set a timer that calls a function that hides the dropdown. lets say the timer is 1 second. on both kind of item mouse-in even, you clear this timer (see the w3school page on timing for syntax, etc). plus, in the navigator's mouse-in you have to show the dropdown.
Another issue with the timer in your code is that it will always execute when mouse-out. Due to the 3 seconds delay you might very well trigger it again when mouse-over but since the timer still exist it will fade out despite you actually have the mouse over the element.
Moving the mouse back and forth quickly will trigger multiple timers.
Try to get it to work without the timer first, then (if really needed) add the additional complexity with the delay (which you must keep track of and remove/reset depending on state).
Here was the final working code, for anyone who comes across this again. Feel free to let me know if I could have improved it in any ways:
$(document).ready(function() {
var dropdown = $('span.hide_me');
var navigator = $('a.paginate_link');
dropdown.hide();
$(navigator).hover(function(){
clearTimeout(emptyTimer);
$(this).siblings(dropdown).fadeIn();
}, function(){
emptyTimer = setTimeout(function(){
dropdown.fadeOut();
}, 500);
});
$(dropdown).hover(function(){
clearTimeout(emptyTimer);
}, function(){
emptyTimer = setTimeout(function(){
dropdown.fadeOut();
}, 500);
});
});

Categories