10

I'm trying get the text value of clicked element (any element) on the website, return it from javascript to Selenium (Python) and use that information to put every clicked element in my log. Is that even possible to achieve using selenium and javascript?

This function can display the element, but won't return anything (normal onclick behaviour). I know that I can read text from alert pop-ups using selenium, but it will make my browser flash on every mouse click.

function getEl()
{
   var ev = arguments[0] || window.event,
   origEl = ev.target || ev.srcElement;
   alert(origEL.text)
}

document.onclick = getEl;

Trying to access javascript console.log doesn't seem to work in Selenium right now so using console.log is not the right answer.

I can detect when a certain element was clicked by writing something to localstorage on click event and then checking the value in localstorage in python. But it's not universal. I need to find and set up every element that I want to observe.

function find_element() 
{
   aTags = document.getElementsByTagName("a");
   searchText = "comments";
   for (var i = 0; i < aTags.length; i++) 
   {
      if (aTags[i].textContent == searchText) 
      {
         found = aTags[i];
         return found;
      }
   }
}

found=find_element();

function saveEvent()
{
   localStorage.setItem("ZAD1.1", "1"); 
}

if(found)
{

   found.addEventListener("click",saveEvent,false);

   var x=localStorage.getItem("ZAD1.1");
   if (x=="1")
   {
       count="comments link was clicked";
       return count;
   } 
}

After that you invoke javascript from python selenium

z=driver.execute_script(javascript1)
if z=="comments link was clicked":
        #do something with this information

Is there any way to get information about objects clicked by user in the browser? I'm using Selenium with Firefox.

EDIT: You can get every clicked element by using getEL() and writing every onclick output in localstorage.

localStorage.setItem(origEl.text, origEl.text);

Create local storage and then write temp as array or string

var temp="VISITED LINKS : "
for (var i = 0; i < localStorage.length; i++){
temp +=localStorage.getItem(localStorage.key(i))+" ";}
return temp

Then you can return the entire list to python.

Reading localStorage content in Selenium (Python2)

Can you think of any other way to send clicked objects to python?

  • Why you want to send it to selenium? Why you won't just send that information to some python http server? – Rafał Łużyński Dec 14 '15 at 15:49
  • Because I want to use that Selenium Script to be a part of my examination application that runs locally. My current script starts firefox profile and then checks if you have clicked in the right link. When you do that it gives you a point. I know that Selenium wasn't designed to monitor user input, but I think this can be done. Monitoring javascript starts on every visited webpage. I don't know any open-source tool to monitor what exactly has the user clicked on the webpage. POSTS and GETS are not enough in my case. – James_Owens_7 Dec 14 '15 at 15:55
  • This is how it looks like in action. [link](http://s7.postimg.org/yox2swzy2/click.jpg) – James_Owens_7 Dec 14 '15 at 16:04
  • 1
    I doubt selenium can be used that way. Javascript has no api to communicate directly with selenium driver. Only way I can think of is to communicate with your own application server via ajax or websockets. – Rafał Łużyński Dec 14 '15 at 16:12
  • Ok. I'll think about it. Right now I can return values from javascript to python but I have to set up a check for every one element on the website manually and only indirectly (as you can see in the linked image and second code fragment). Searching for another way to return value from onclick event brought me nothing. It kind of works but it's a pain to set up everything. Thanks for your input. – James_Owens_7 Dec 14 '15 at 16:20
  • how are you returning data to python from js? – Rafał Łużyński Dec 14 '15 at 16:24
  • `if (!found){ count="NIE TA STRONA"; return count; } var x=localStorage.getItem("ZAD1.1") if (x=="1") {count="OUR LINK GOT CLICKED"; return count;}` I'm returning count value at the end of javascript and then get returned value in python by invoking `z=driver.execute_script(javascript1)` – James_Owens_7 Dec 14 '15 at 16:27

2 Answers2

4

If I understand this correctly, you're just trying to get notified when any element on the page is clicked, so that you can do something with that information?

You want a global event handler.

In pure vanilla JavaScript, that goes like this:

document.body.onclick = function(e) {
    console.log(e);           // `e` is the click event
    console.log(e.target);    // `e.target` is the element that was clicked
    // do something with this information
}

When you want to "do something with this information", you have a number of options, as you seem to have worked out. The best thing you can do here is to send an AJAX request to a HTTP server you control, whereupon the receiving server-side script could log the details to file (or whatever you do with it).

Your code indicates that when something is clicked, you want to save that to localStorage - I'd recommend you save stringified base64 encoded JSON, containing the target element of every click event. Here's some code you can use to do that:

/**
 * Constant. This is the (string) key name of the 
 * save location in localStorage.
 */
var locationName = "myNamespace_clicks";

/**
 * Given an object, will JSON- and base64-encode
 * that object so it can be stored in localStorage.
 */
function encodeForStorage(dataObject) {
    return btoa(JSON.stringify(dataObject));
}

/**
 * Given a string from localStorage, will decode that
 * string from JSON and base64 to a JS object.
 */
function decodeStoredObject(dataString) {
    return JSON.parse(atob(dataString));
}

/**
 * Given an item, will add this item to the data stored
 * in localStorage, and then save the new data.
 */
function addItemToStorage(item) {
    var rawStoredData = localStorage.getItem(locationName);
    var dataObject;

    if(rawStoredData) {
        dataObject = decodeStoredObject(rawStoredData);
    }
    else {
        dataObject = {
            "clicks": []
        }
    }

    dataObject["clicks"].push(item);

    localStorage.setItem(locationName, encodeForStorage(dataObject));
}

document.body.onclick = function(e) {
    addItemToStorage(e.target);
}
Thomas Owens
  • 114,398
  • 98
  • 311
  • 431
ArtOfCode
  • 5,702
  • 5
  • 37
  • 56
1

In the end I will probably use the window.name global variable. Unlike LocalStorage it stores information about clicked urls between page changes. LocalStorage can not save any data on page change.

https://stackoverflow.com/a/1981681/5678519

Community
  • 1
  • 1