title: How do I access an iframe from CasperJS?
body: <p>I have a webpage with an iframe.  I'd like to access the contents of the iframe using <a href="http://www.casperjs.org">CasperJS</a>.  In particular, I need to click buttons and fill a form.  How can I do that?</p>
  
  <p>The main webpage is
  <a href="http://jim.sh/~jim/tmp/casper/main.html">main.html</a>:</p>
  
  <pre><code>&lt;html&gt;&lt;body&gt;
  &lt;a id='main-a' href="javascript:console.log('pressed main-a');"&gt;main-a&lt;/a&gt;
  &lt;iframe src="iframe.html"&gt;&lt;/iframe&gt;
  &lt;a id='main-b' href="javascript:console.log('pressed main-b');"&gt;main-b&lt;/a&gt;
  &lt;/body&gt;&lt;/html&gt;
  </code></pre>
  
  <p>The iframe is:</p>
  
  <pre><code>&lt;html&gt;&lt;body&gt;
  &lt;a id='iframe-c' href="javascript:console.log('pressed iframe-c');"&gt;iframe-c&lt;/a&gt;
  &lt;/body&gt;&lt;/html&gt;
  </code></pre>
  
  <p>My naïve approach:</p>
  
  <pre><code>var casper = require('casper').create({
      verbose: true,
      logLevel: "debug"
  });
  
  casper.start("http://jim.sh/~jim/tmp/casper/main.html", function() {
      this.click('a#main-a');
      this.click('a#main-b');
      this.click('a#iframe-c');
  });
  
  casper.run(function() {
      this.exit();
  });
  </code></pre>
  
  <p>Doesn't work, of course, because the <code>a#iframe-c</code> selector isn't valid in the main frame:</p>
  
  <pre><code>[info] [phantom] Starting...
  [info] [phantom] Running suite: 2 steps
  [debug] [phantom] opening url: http://jim.sh/~jim/tmp/casper/main.html, HTTP GET
  [debug] [phantom] Navigation requested: url=http://jim.sh/~jim/tmp/casper/main.html, type=Other, lock=true, isMainFrame=true
  [debug] [phantom] url changed to "http://jim.sh/~jim/tmp/casper/main.html"
  [debug] [phantom] Navigation requested: url=http://jim.sh/~jim/tmp/casper/iframe.html, type=Other, lock=true, isMainFrame=false
  [debug] [phantom] Successfully injected Casper client-side utilities
  [info] [phantom] Step 2/2 http://jim.sh/~jim/tmp/casper/main.html (HTTP 200)
  [debug] [phantom] Mouse event 'click' on selector: a#main-a
  [info] [remote] pressed main-a
  [debug] [phantom] Mouse event 'click' on selector: a#main-b
  [info] [remote] pressed main-b
  [debug] [phantom] Mouse event 'click' on selector: a#iframe-c
  FAIL CasperError: Cannot dispatch click event on nonexistent selector: a#iframe-c
  #    type: uncaughtError
  #    error: "CasperError: Cannot dispatch click event on nonexistent selector: a#iframe-c"
  CasperError: Cannot dispatch click event on nonexistent selector: a#iframe-c    
    /tmp:901 in mouseEvent
    /tmp:365 in click
    /tmp/test.js:9
    /tmp:1103 in runStep
    /tmp:324 in checkStep
  </code></pre>
  
  <p>Is there any way to make this work?  A hack that involves poking into phantomjs directly would be fine, but I don't know what to do there.</p>
  
  <p>I'm using CasperJS version 1.0.0-RC1 and phantomjs version 1.6.0.</p>