0

For some reason I can't switch to nested frames in selenium-webdriver using node.js. I have tried setting timeouts to let the page load or timeouts to give the driver time to switch to another frame, nothing worked. This question is most likely a continuation of this. I am getting a NoSuchFrameError.

HTML - full url here

<!DOCTYPE html>
<html>
<head>
<title>HTML Target Frames</title>
</head>


<frameset rows="16%,84%">
    <frame src="./framesHtml/top.htm" name="top_page" >
    <frameset cols="50%,50%">
        <frame src="./framesHtml/menu.htm" name="menu_page" >
        <frame src="./framesHtml/main.html" name="main_page" >
    </frameset>
</frameset>
</html>

Function switching to main_page

var webdriver = require('selenium-webdriver');
var chrome = require('selenium-webdriver/chrome');
var chromePath = require('selenium-chromedriver').path;
var FrameHandler = require('../../JS-Selenium-Toolkit/src/FrameHandler');
var expect = require('chai').expect;

describe('FrameHandler', function () {
  it('Should pass if the set frame is main_page', function (done) {
    this.timeout(15000);

    var service = new chrome.ServiceBuilder(chromePath).build();
    chrome.setDefaultService(service);

    var chromeDriver = new webdriver.Builder()
        .withCapabilities(webdriver.Capabilities.chrome())
        .build();

    var frameHandler = new FrameHandler(chromeDriver);

    //check current frame name
    frameHandler.getCurrentFrameName(function (name) {
        console.log(name + ' current frame inside second function');
    });

  chromeDriver.get('http://orasi.github.io/Selenium-Java-Core/sites/unitTests/orasi/utils/frameHandler.html').then(function () {
    frameHandler.switchToFrame('top_page').then(function () {
        frameHandler.switchToFrame('main_page').then(function () {
            frameHandler.getCurrentFrameName(function (name) {
                console.log(name + ' this frame was switched to ');
                expect(name).to.equal('main_page');
                done();
            });
        });
     });
  });
 });
});

FrameHandler Object

var webdriver = require('selenium-webdriver');

var FrameHandler = function (driver) {

    this.switchToFrame = function (name)
    {
            if (typeof name !== 'string' || name === '' || !name)
            {
                console.log('error');
            }
            else
            {
                console.log(this.getCurrentFrameName(function (name) {
                    console.log(name + ' this is the current frame before switch');
                }));

                console.log(name + ' switch to this frame');
                return driver.switchTo().frame(name);
            }
    };

    this.getCurrentFrameName = function (callback)
    {
        driver.executeScript('return self.name').then(function (name)
        {
            return callback(name);
        });
    };
};

module.exports = FrameHandler;
Community
  • 1
  • 1
Grim
  • 2,398
  • 4
  • 35
  • 54

2 Answers2

0

I haven't verified myself with your example, but the consensus is that you cannot switch directly to a nested <frame> from the top-level, you need to switch into a parent <frame> first.

In other words, into 'top_page', then into 'main_page'.

See the top answers to:

Community
  • 1
  • 1
Andrew Regan
  • 5,087
  • 6
  • 37
  • 73
  • I looked at both of those resources before asking this question and I was unable to develop a solution. I just tried again by adding driver.switchTo.frame('top_page'); after this.timeout(milliseconds) in the test case. Could this be a problem with asynchronous programming? Maybe I am not handling my promises correctly? – Grim Mar 02 '16 at 14:33
  • I am still new to node.js and I am just now grasping the concepts of asynchronous programming using callbacks and promises. – Grim Mar 02 '16 at 14:35
  • 1
    Possibly... is there a reproducible testcase so I can test this properly myself? Or is there somewhere you can upload all the pages and JS? – Andrew Regan Mar 02 '16 at 14:38
  • Please see my edit and if its not enough information to reproduce please let me know. – Grim Mar 02 '16 at 15:22
  • I was able to find what was causing the problem for this but wasn't able to develop a solution. Do you know where I can submit an issue or bug report for this? The driver used is selenium-chromedriver – Grim Mar 02 '16 at 18:19
  • Probably here: https://github.com/SeleniumHQ/selenium/issues. Thanks for the edit but I wasn't able to get the test working. Is it complete? – Andrew Regan Mar 02 '16 at 18:35
  • I forgot to add the service and the initiation of the webdriver. Please see the two new variables after this.timeout in the it() function. The only thing that should keep you from running the test case is using the same modules. – Grim Mar 02 '16 at 18:42
  • i am such an idiot, I just tried to reproduce from the example and I left two things out the ); at the very end of the test case and the initialization of the frameHandler variable, please just copy and paste the updated unit test above. – Grim Mar 02 '16 at 18:59
0

After further testing and switching drivers I found that the chrome driver doesn't support nested framesets. I tried going from top_page to menu_page and also tried just going directly to the menu_page, neither worked. I tried all types of solutions and was unable to get anything to work until I switched from the chrome driver to ie or firefox. I also tried removing the nested frameset in the html file and then running the chrome driver, the test case passed. So this is in fact an issue with nested framesets and the chrome driver. I really need to get a fix for this as this can affect automation using the chrome driver.

Grim
  • 2,398
  • 4
  • 35
  • 54