0

I want to simulate mouse hover on this site on this element using only javascript with selenium.

#main > div > div > div.Blockreact__Block-sc-1xf18x6-0.elqhCm > div > div.fresnel-container.fresnel-greaterThanOrEqual-xl.fill-remaining-height > div > div.Blockreact__Block-sc-1xf18x6-0.Flexreact__Flex-sc-1twd32i-0.FlexColumnreact__FlexColumn-sc-1wwz3hp-0.bEcedX.jYqxGr.ksFzlZ > div.Blockreact__Block-sc-1xf18x6-0.duVYOV > div > div.PriceHistory--graph > div > div > div.recharts-wrapper > svg > g.recharts-layer.recharts-bar > g > g:nth-child(80)

I have looked at various posts like this and this. However, nothing seems to be working on this site.

I tried using this code, but it isn't working on the site.

const mouseoverEvent = new Event('mouseover');
$('#main > div > div > div.Blockreact__Block-sc-1xf18x6-0.elqhCm > div > div.fresnel-container.fresnel-greaterThanOrEqual-xl.fill-remaining-height > div > div.Blockreact__Block-sc-1xf18x6-0.Flexreact__Flex-sc-1twd32i-0.FlexColumnreact__FlexColumn-sc-1wwz3hp-0.bEcedX.jYqxGr.ksFzlZ > div.Blockreact__Block-sc-1xf18x6-0.duVYOV > div > div.PriceHistory--graph > div > div > div.recharts-wrapper > svg > g.recharts-layer.recharts-bar > g > g:nth-child(80)').dispatchEvent(mouseoverEvent)

Due to some problems I can only use javascript and not Actionchains like most posts describe. Any solution without ActionChains should work fine.

I just want to get the data that is displayed after the mouse hover event is triggered. It can be done manually and with ActionChains but I want it to be done with JS. Link to the screenshot As It can be seen from the image a tooltip appears after the mouse hovers on the graph. I can simulate the behaviour with ActionChains by using this code.

#Scroll a little bit to load all the elements
driver.execute_script("window.scrollTo(0, 500);")
 
XPath = "//*[@class='recharts-layer recharts-bar-rectangle']"
bar = driver.find_elements('xpath',XPath)[-1] #Since I want to get the latest data
ActionChains(driver).move_to_element(bar).perform()

#Now get the data
XPATH_TOOLTIP = "//div[@class='PriceHistory--tooltip']"
data = driver.find_element('xpath',XPATH_TOOLTIP).text
print(data)

I want the tooltip to appear using JS.

Is it possible to simulate the mouse hover on the element? Also, why does the code work on some sites but not on others, for example, works on this?

shahrOZe
  • 105
  • 1
  • 5

1 Answers1

1

Here are 2 ways your question can be interpreted :-

Case 1: You just want the "element hovered" event to get fired, and are not concerned for the mouse pointer to itself go over the element.

Case 2: You want the mouse pointer to itself move to the spot where the element is and in that way (graphically, so to speak) hover over it.

SOLUTIONS :-

Case 1: This is the JavaScript code you could execute using selenium:

// - THIS IS FOR DEMO, TO CHECK IF ELEMENT WAS HOVERED -
element.addEventListener('mouseover', function() {
  console.log('Event triggered');
});
// - THIS IS FOR DEMO, TO CHECK IF ELEMENT WAS HOVERED -


// Selecting the Element
var element = document.querySelector('#main > div > div > div.Blockreact__Block-sc-1xf18x6-0.elqhCm > div > div.fresnel-container.fresnel-greaterThanOrEqual-xl.fill-remaining-height > div > div.Blockreact__Block-sc-1xf18x6-0.Flexreact__Flex-sc-1twd32i-0.FlexColumnreact__FlexColumn-sc-1wwz3hp-0.bEcedX.jYqxGr.ksFzlZ > div.Blockreact__Block-sc-1xf18x6-0.duVYOV > div > div.PriceHistory--graph > div > div > div.recharts-wrapper > svg > g.recharts-layer.recharts-bar > g > g:nth-child(80)');

// CREATING AN EVENT FOR HOVER
var event = new MouseEvent('mouseover', {
  'view': window,
  'bubbles': true,
  'cancelable': true
});

// DISPATCHING THE EVENT, i.e., ACTUALLY HOVERING
element.dispatchEvent(event);

If, after executing it, all went well, you should see an "Event triggered" message displayed on the console of the browser.

Case 2:

There is no way, that i know of, through which you can pull that off, without using selenium. As you mentioned ActionChains cannot be used so that too is a problem.

In case you just cannot use ActionChains, but can use Selenium (which I know is not what you asked for), You could use the following step-by-step guide:

STEP 1: Maximise the window [Required for Step 4]

STEP 2: Get the scrollY position of the element you want to hover over (using Javascript).

STEP 3: Scroll to the element using the scrollTo method (again using Javascript) 

STEP 4: You could use an alternative to PyAutoGui (which is a python library; you can use it if you are using python) that allows you to take the screenshot of the page, and then search for the image of the element throughout the page (using the `locateOnScreen` method).

STEP 5: Once you have gotten the position on screen, you could move the cursor to that position, again using an alternative of PyAutoGui (or itself if you're using python), like in STEP 4.

The last answer is quite complicated, and should be used only if you are desperate enough to do the task in a graphical way, and cannot find a better answer :)

HerrAlvé
  • 587
  • 3
  • 17
  • I am only concerned with getting the data after the hovering. The solution one doesn't seem to show the data. Please check the edits – shahrOZe Mar 03 '22 at 08:21
  • 1
    Hello, @shahrOZe! When I tried to run a querySelector for that element on the website you've provided, it returns null. It would be helpful if you could check to see if that element even exists, i.e., if you need to be logged in for that element to appear, or if you need to click on some buttons before it appears ¯\_(ツ)_/¯ – HerrAlvé Mar 03 '22 at 12:44
  • Actually what I want to do is get the data displayed when the mouse is hovered on the line graph in the activity section. I am able to do it using actionChains but my task requires it to not use actions chains and do it with js or any other means. The reason to not use actionChains is because it doesn't work when browser is minimized. – shahrOZe Mar 03 '22 at 12:57
  • 1
    Could you execute this line of code in your browser's console and check if you get null or not? `document.querySelector("#main > div > div > div.Blockreact__Block-sc-1xf18x6-0.elqhCm > div > div.fresnel-container.fresnel-greaterThanOrEqual-xl.fill-remaining-height > div > div.Blockreact__Block-sc-1xf18x6-0.Flexreact__Flex-sc-1twd32i-0.FlexColumnreact__FlexColumn-sc-1wwz3hp-0.bEcedX.jYqxGr.ksFzlZ > div.Blockreact__Block-sc-1xf18x6-0.duVYOV > div > div.PriceHistory--graph > div > div > div.recharts-wrapper > svg > g.recharts-layer.recharts-bar > g > g:nth-child(80)")` – HerrAlvé Mar 03 '22 at 13:54
  • It returns the element. The reason it shows null on your side is because the elements of the chart aren't loaded. Can you please try to scroll down to locate the graph. I will rephrase my question so it is more clear. – shahrOZe Mar 03 '22 at 13:58
  • 1
    Have you tried running selenium in headless mode? Be sure to add these arguments in. `chromeOptions.addArguments("--headless") chromeOptions.addArguments("--no-sandbox") chromeOptions.addArguments("--disable-dev-shm-usage") chromeOptions.addArguments("--window-size=1920x1080") chromeOptions.addArguments("start-maximised")` – HerrAlvé Mar 04 '22 at 16:39
  • headless mode won't work on this site, I am using a modified selenium. https://github.com/ultrafunkamsterdam/undetected-chromedriver – shahrOZe Mar 04 '22 at 17:37