Accessing frames in HTML from Squish for Web

Last edited on

Requirements and verifying accessibility of frames

Using Squish with websites that use frames (either frameset or iframe) requires that all frames are being accessible from the toplevel web page being loaded. This is necessary so that Squish can hook itself up for event recording as well as lookup objects within the frames.

This requirement can be verified by loading the webpage into any browser and opening up the browsers development tools. Specifically the Console that allows you to execute Javascript statements within the content of the webpage. The following script snippet can be pasted and executed in the Console, and will list any frames that cannot be accessed. Starting with the 6.5.2 release Squish will also add a message to the Console log when it encounters a non-hookable frame.

(function () {
    function path(elem) {
      function elementIndex(elem) {
        var cnt = 1;
        var sibling = elem;
        while(sibling = sibling.previousElementSibling) {
          if (sibling.tagName == elem.tagName) {
            cnt++;
          }
        }
        return cnt;
      }
      if (elem === document) {
        return "DOCUMENT";
      }    
      return path(elem.parentNode) + "." + elem.tagName + elementIndex(elem);
    }
    function elementsByTagName(tagName) {
      return Array.prototype.slice.call(document.getElementsByTagName(tagName));
    }
    var allframes = elementsByTagName("FRAME").concat(elementsByTagName("IFRAME"));
    for (var i = 0; i < allframes.length; ++i) {
      var frame = allframes[i];
      try {
        var body = frame.contentWindow.document.body;
        var href = frame.contentWindow.lo`cation.href;
      } catch( err ) {
        console.log("Frame " + i + ", at path " + path(frame) + " with src: " + frame.src + " cannot be accessed: " + err);
      }
    }
})();

In case the script snippet does not report any frames as being inaccessible Squish will be able to hook into the frames, record interactions and replay those recorded interactions.

Note: At the moment, accessing the content of the pages in frames through the Application Objects view requires picking an object inside the frame. Expanding the FRAME elements in the view will not show the page contents below it.

Making inacessible frames accessible

In case a frame is being reported as inaccessible, this is most often due to the same-origin-policy being violated. This policy requires that the web content loaded into the frame has the same ‘origin’ as the parent page that embeds the frame. You can find a rather extensive explanation of this policy and what ‘origin’ means on the Mozilla Developer Website.

If the same-origin-policy is violated Squish won’t be able to access the content of the frames that have a different origin. The browsers do not offer options to disable these checks, so the only way to enable access for Squish is to adjust the websites. There are two modifications possible, either of them will fix the issue:

  1. Ensure that the content shown in the frame is being loaded from the same HTTP server as the original page, i.e. it has to use the same protocol (http vs. https), the same server name or IP address and usually also the same port number.

  2. All involved pages need to set the document.domain javascript property of their document to the same valid value. Again the Mozilla Developer Website has a rather good explanation how to do this and what valid values are possible.

You can test changes done to the website for points 1. or 2. by running the javascript snippet above again.

Webpages nesting frames inside frames

In case any of the websites displayed in a frame again has frames themselves you’ll need to run the above snippet in the context of each frame that has such nested frames. How this can be done depends on the Browser, but often there’s a dropdown indicating the context directly above the console. It will likely say ‘top’ by default, meaning the script is executed in the toplevel website. Opening the dropdown should reveal entries related to the html pages shown in the frames and after selecting one of them any subsequent code executions are being done inside the context of that document.

Alternatively a Squish package that includes the logging of non-hookable frames can be used to gather details about the nested frames that cannot be hooked in the Console log.