Languages
[Edit]
EN

JavaScript - mouse click by selector macro player for web page

7 points
Created by:
Marcin
2477

In this post simple mouse click macro player has been presented.

Most important features of macro player are:

  • defining ordered click operations to execute,
  • switching between frames/iframes if they are avaialble on web page,
  • waiting until element will be available,
  • timeout to prevent infinite waiting.

1. Mouse click macro player example

This example shows how to simulate simple cliking.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <script>

    function executeMouseClick(selectors, onFinished, root, limit) {
        var iteration = 0;
        
        if (limit == null) {
            limit = 1000;
        }

        function findShadow(selector, callback, root) {
            if (iteration < limit) {
                var replacement = selector(root);

                if (replacement) {
                    if(callback) {
                        callback(replacement);
                    }
                } else {
                    function proxy() {
                        findShadow(selector, callback, root);
                    }

                    setTimeout(proxy, 100);
                }

                iteration += 1;
            } else {
                if (onFinished) {
                    onFinished(false, 'Timeout exceeded!');
                }
            }
        }

        function clickElement(selector, callback, root) {
            if(iteration < limit) {
                var element = root.querySelector(selector);

                if (element) {
                    element.click();

                    if (callback) {
                        callback(root);
                    }
                } else {
                    function proxy() {
                        clickElement(selector, callback, root);
                    }

                    setTimeout(proxy, 100);
                }

                iteration += 1;
            } else {
                if (onFinished) {
                    onFinished(false, 'Timeout exceeded!');
                }
            }
        }

        function makeIteration(index, root) {
            if (index < selectors.length) {
                var selector = selectors[index];

                function proxy(root) {
                    makeIteration(++index, root);
                }

                if (selector instanceof Function ) {
                    findShadow(selector, proxy, root);
                } else {
                    clickElement(selector, proxy, root);
                }
            } else {
                if (onFinished) {
                    onFinished(true, root);
                }
            }
        }

        makeIteration(0, root || document);
    }

  </script>
</head>
<body>
  <button title="Button 1" onclick="console.log('Button 1')">Button 1</button>
  <button class="button-2" onclick="console.log('Button 2')">Button 2</button>
  <button onclick="simulateClicking()">Simulate buttons clicking</button>
  <script>

    function simulateClicking() {
		var selectors = [
          	'[title="Button 1"]',
          	'.button-2'
        ];

        function onFinished(result, root) {
			if (result) {
				console.log('All buttons clicked!');
			} else {
				console.log('Macro timeout!');
			}
        }

        executeMouseClick(selectors, onFinished);
  	}

  </script>
</body>
</html>

2. Mouse click macro player with waiting for button example

In this example waiting when button will be added has been shown.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <script>

    function executeMouseClick(selectors, onFinished, root, limit) {
        var iteration = 0;
        
        if (limit == null) {
            limit = 1000;
        }

        function findShadow(selector, callback, root) {
            if (iteration < limit) {
                var replacement = selector(root);

                if (replacement) {
                    if(callback) {
                        callback(replacement);
                    }
                } else {
                    function proxy() {
                        findShadow(selector, callback, root);
                    }

                    setTimeout(proxy, 100);
                }

                iteration += 1;
            } else {
                if (onFinished) {
                    onFinished(false, 'Timeout exceeded!');
                }
            }
        }

        function clickElement(selector, callback, root) {
            if(iteration < limit) {
                var element = root.querySelector(selector);

                if (element) {
                    element.click();

                    if (callback) {
                        callback(root);
                    }
                } else {
                    function proxy() {
                        clickElement(selector, callback, root);
                    }

                    setTimeout(proxy, 100);
                }

                iteration += 1;
            } else {
                if (onFinished) {
                    onFinished(false, 'Timeout exceeded!');
                }
            }
        }

        function makeIteration(index, root) {
            if (index < selectors.length) {
                var selector = selectors[index];

                function proxy(root) {
                    makeIteration(++index, root);
                }

                if (selector instanceof Function ) {
                    findShadow(selector, proxy, root);
                } else {
                    clickElement(selector, proxy, root);
                }
            } else {
                if (onFinished) {
                    onFinished(true, root);
                }
            }
        }

        makeIteration(0, root || document);
    }
    
    // this function is not part of executeMouseClick function
    // more details about function here: https://dirask.com/q/aDWV81
    function makeLoop(count, duration, onIteration) {
      	var index = 0;
      	var sleep = duration / count;
      
    	function action() {
        	if (index < count) {
                onIteration(index++);
              
            	setTimeout(action, sleep);
            }
        }
      
      	if (index < count) {
      		setTimeout(action, sleep);
        }
    }
    
    // this function is not part of executeMouseClick function
    function appendButton(number) {
    	var button = document.createElement('button');
           
        button.onclick = function() {
          console.log('Button ' + number + ' clicked!');
        };

        button.className = 'button-' + number;
        button.innerText = 'Button ' + number;

        document.body.appendChild(button);
    }

  </script>
</head>
<body>
  <p>
      Click on "Simulate buttons clicking" before 
      waiting for button will be finished if you
      want to see effect of waiting for second button.
  </p>
  <button title="Button 1" onclick="console.log('Button 1 cliked!')">
      Button 1
  </button>
  <button onclick="simulateClicking()">
      Simulate buttons clicking
  </button>
  <script>

    function simulateClicking() {
		var selectors = [
          	'[title="Button 1"]',
          	'.button-2'
        ];

        function onFinished(result, root) {
			if (result) {
				console.log('All buttons clicked!');
			} else {
				console.log('Macro timeout!');
			}
        }

        executeMouseClick(selectors, onFinished);
  	}

    // Button 2 will be added after 5 seconds
    makeLoop(5, 5000, function(index) {
      
      	var iteration = index + 1;
        console.log('... Waiting for button (iteration: ' + iteration + '/5).');
        
         if (iteration == 5) {
            appendButton(2);
	        console.log('--> Button added!');
        }
    }, 5000);

  </script>
</body>
</html>

2. Mouse click macro player with button inside iframe example

In this example accessing to button inside iframe has been shown.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <script>

    function executeMouseClick(selectors, onFinished, root, limit) {
        var iteration = 0;
        
        if (limit == null) {
            limit = 1000;
        }

        function findShadow(selector, callback, root) {
            if (iteration < limit) {
                var replacement = selector(root);

                if (replacement) {
                    if(callback) {
                        callback(replacement);
                    }
                } else {
                    function proxy() {
                        findShadow(selector, callback, root);
                    }

                    setTimeout(proxy, 100);
                }

                iteration += 1;
            } else {
                if (onFinished) {
                    onFinished(false, 'Timeout exceeded!');
                }
            }
        }

        function clickElement(selector, callback, root) {
            if(iteration < limit) {
                var element = root.querySelector(selector);

                if (element) {
                    element.click();

                    if (callback) {
                        callback(root);
                    }
                } else {
                    function proxy() {
                        clickElement(selector, callback, root);
                    }

                    setTimeout(proxy, 100);
                }

                iteration += 1;
            } else {
                if (onFinished) {
                    onFinished(false, 'Timeout exceeded!');
                }
            }
        }

        function makeIteration(index, root) {
            if (index < selectors.length) {
                var selector = selectors[index];

                function proxy(root) {
                    makeIteration(++index, root);
                }

                if (selector instanceof Function ) {
                    findShadow(selector, proxy, root);
                } else {
                    clickElement(selector, proxy, root);
                }
            } else {
                if (onFinished) {
                    onFinished(true, root);
                }
            }
        }

        makeIteration(0, root || document);
    }

  </script>
</head>
<body>
  <button title="Button 1" onclick="console.log('Button 1 cliked!')">
      Button 1
  </button>
  <button onclick="simulateClicking()">
      Simulate buttons clicking
  </button>
  <br /><br />
  <iframe id="my-frame"></iframe>
  <script>
    
    var frame = document.getElementById('my-frame');
    var root = frame.contentDocument;
    
    root.open();
    root.write('<button title="Button 2" onclick="alert(\'Iframe button: Clicked!\')">Click me!</button>');
    root.close();

    function simulateClicking() {
		var selectors = [
          	'[title="Button 1"]',
          	function(root) { // this function goes inside iframe switching root
              	// root variable represents active root e.g. document
              	var frame = root.getElementById('my-frame');
              
              	if (frame)
                  	return frame.contentDocument; // it will be from now new root
              
              	return null; // null affects waiting for iframe
            },
          	'[title="Button 2"]'
        ];

        function onFinished(result, root) {
			if (result) {
				console.log('All buttons clicked!');
			} else {
				console.log('Macro timeout!');
			}
        }

      	// this function starts with root document abject as root
        executeMouseClick(selectors, onFinished, document);
  	}

  </script>
</body>
</html>

 

Hey ūüĎč
Would you like to know what we do?
  • Dirask is a friendly IT community for learners, professionals and hobbyists to share their knowledge and help each other in extraordinary easy way.
  • We welcome everyone,
    no matter what the experience,
    no matter how basic the question is,
    this community will help you.