4

I am trying to create web automation for a site. I am simulating clicks. Usually I add an ID to an element like below and trigger a click using the Chrome developer console and it always works.

p.s: below question is outdated.I am actually trying to click an item from context menu in web.whatsapp.com

<div id="myapp">button1</div>

<script>
  $("#myapp").click();
</script>

Or, if that won't work, I use a mousedown event using pure JavaScript like below and it will work smoothly.

function triggerMouseEvent(node, eventType) {
  var clickEvent = document.createEvent('MouseEvents');
  clickEvent.initEvent(eventType, true, true);
  node.dispatchEvent(clickEvent);
}

var targetNode = document.querySelector("#myapp");
triggerMouseEvent(targetNode, "mousedown");

Now my question is: this is not working for the menu that is generated via the jQuery contextMenu plugin.

You can see the demo for contextMenu here, where I am testing the above via the developer console.

So when you right click on the context menu there is a list of menu items listed with ul and li tags.I manually added ID #myapp to one of menu and with below code it is also choosing correct element via developer console.

var targetNode = document.querySelector("#myapp");
targetNode;

But I am unable to trigger a click on that menu item generated via context menu. I was struggling with it for more than 24 hours. I tried all events in JavaScript that I could think of, like mouseup, mousedown, and mouseenter.

Vishnu
  • 2,372
  • 6
  • 36
  • 58

1 Answers1

3

You can only click the menu items when the context menu is created, which is done dynamically by the plugin. So, we first need to trigger the menu.

Triggering a native context menu is not possible, as far as I know. Triggering a right click however is possible, you need to use the contextmenu event.

In particular, using $(el).trigger('contextmenu') seems to work fine. This seems to be working because the plugin explicitly supports this. When that is done, we need to trigger a click on the menu item we want to click on.

// first, trigger the context menu
$('.button-that-has-contextmenu').trigger('contextmenu');
// then click the menu item you want to click
// substitute the correct index in `eq(X)` here
$('.context-menu-item:eq(1)').trigger('mouseup');

Because this plugin is not hosted on a CDN, it is not easy to create a snippet here. I have however created a JSFiddle to demo this fully, where I copy + pasted the plugin source into the fiddle.


In the comments, you asked about web.whatsapp.com. I happen to have a WhatsApp account and tested it there. It seems that they are not using the jQuery contextMenu plugin. A $ function is indeed defined, but it appears not to be jQuery, but just a shortcut to document.querySelector.

What their custom context menu code is I don't know, but I did manage to trigger it. Basically, I used the vanilla JS version of the above code and then had to figure out which element to trigger. The latter was easier than I thought. There is a list of chats that is open, .infinite-list-item elements. Their order in the DOM does not match the visual order, but finding the one you want can be done using the browser inspector for example. Given that you have that, you want the .chat element inside of that list item. Say we are interested in the second item, we can select it as follows:

var target = $('.infinite-list-item:nth-child(2) .chat');

You can check in the browser console that you got the right element. Then, fire an event as follows.

var evt = new MouseEvent('contextmenu', {
      bubbles: true,
      cancelable: true,
      view: window,
      buttons: 2
    });
target.dispatchEvent(evt);

This uses the modern MouseEvent constructor, code is based on this example.

The above will open the context menu in the upper left corner of your browser. You can change the position by passing a clientX and clientY property into the MouseEvent constructor, that represent a position in the window.

When that is done, you can click the items in the context menu. Except you cannot automate this using JavaScript. I peeked at the source and the click handler of those menu items checks if event.isTrusted, meaning that you cannot programmatically trigger a click on them.

You may want to look into using something that can emulate clicks on a lower level, like Selenium 2.0 (WebDriver), or some wrapper around it like WebdriverIO.

Community
  • 1
  • 1
Just a student
  • 10,560
  • 2
  • 41
  • 69
  • Hey thank you for solution , but its not working in the place where I am actually testing... Its actually web.whatsapp.com .. if you right click anywhere it lists this contextmenu... Its not working there.. I have put sample html code of it here https://jsfiddle.net/adjmpw/ympnzb1c/4/ .. it works there . but not working in web.whatsapp.com.Maybe its parent is absolutely positioned ? . Please help me , I will give how much ever bounty you want – Vishnu Apr 09 '17 at 17:11
  • Hi , thank you thank you so much ,, I actually able to trigger the context menu using mouseover event and clicking on .icon-down , But unable to click the mute button..now I know why..because of isTrusted.. I am planning to use selenium.. can selenium click those buttons even though there is isTrusted ? can you tell any good javascript wrapper for selenium where this action and any actions are possible. – Vishnu Apr 11 '17 at 01:55
  • You are very welcome! Yes, it will work with Selenium, because there it simulates the clicks and mouse movement on a lower level. I personally don't have experience with any JS wrappers, but you could give WebdriverIO a try, I linked it in my answer. – Just a student Apr 11 '17 at 05:52
  • Let me know if there is anything I can improve in my answer before you award the bounty. – Just a student Apr 12 '17 at 13:36
  • I gave you bounty :) , I tried webdriverJs as you told.. now struck with some problem, if you can solve it I will give you 200 bounty :D -- http://stackoverflow.com/questions/43353279/reopening-same-window-again-in-selenium-webdriverjs – Vishnu Apr 12 '17 at 15:26
  • Thank you so much! Please don't feel obliged to reward me with a bounty, I'm happy to help :-) I'll take a look tomorrow. – Just a student Apr 12 '17 at 19:30