2012-08-27 23 views
31

私はiframeを持つウェブページを持っています。私はCasperJSを使ってiframeの内容にアクセスしたいと思います。特に、ボタンをクリックしてフォームを入力する必要があります。どうやってやるの?CasperJSからiframeにアクセスするにはどうすればよいですか?

メインWebページが main.htmlです:

<html><body> 
<a id='main-a' href="javascript:console.log('pressed main-a');">main-a</a> 
<iframe src="iframe.html"></iframe> 
<a id='main-b' href="javascript:console.log('pressed main-b');">main-b</a> 
</body></html> 

のiframeがある:

<html><body> 
<a id='iframe-c' href="javascript:console.log('pressed iframe-c');">iframe-c</a> 
</body></html> 

マイナイーブなアプローチ:

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(); 
}); 

は動作しません、もちろん、ので、 a#iframe-cセレクタがメインフレームで無効です:

[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 

この方法を使用する方法はありますか?ファントムジを直接的に突き刺すハックは問題ありませんが、私はそこで何をすべきか分かりません。

私はCasperJSバージョン1.0.0-RC1とphantomjsバージョン1.6.0を使用しています。あなたがそれらの iFramesとその内容にアクセスできるようにするためにPhantomjs 1.5によって提供される新しい--web-security=no 機能を使用する必要があります実際のところ

答えて

40

永遠にこれを探していましたが、もちろん私は質問を投稿してから数分後に答えを見つけました。

私はthis commitにphantomjsに追加された新しいフレーム切り替えコマンドを使用できます。具体的には、this.page.switchToChildFrame(0)およびthis.page.switchToParentFrame()が機能します。文書化されていない表示され、また、方法は今後のリリースのためのchangedていたようだが、それは作業を行います。

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.page.switchToChildFrame(0); 
    this.click('a#iframe-c'); 
    this.page.switchToParentFrame(); 
}); 

casper.run(function() { 
    this.exit(); 
}); 
+0

Jim、切り替え後にthis.test.assertVisible( '#someElemInsideIframe')できるかどうか知りましたか?私のためにbarfに見えますが、this.click(...)が動作します。 –

+0

私は、申し訳ありません。可視性は、フレームでうまく動作しない別の方法でテストされるかもしれませんが、わかりません。 –

+1

@ olleolleolleの答えは見ましたか? withFrameは文書化されたメソッドです。 –

4

+1

この例は、同じドメインのiframeで、ドメイン間のセキュリティは私の問題ではありません。何が働いたのか私自身の答えを見てください( '--web-security = no'はそこではまだ必要ありません)。 –

35

1.0からは、withFrame

casper.open("http://www.example.com/page.html", function() { 
    casper.withFrame('flashHolder', function() { 
     this.test.assertSelectorExists('#the-flash-thing', 'Should show Flash'); 
    }); 
    }); 
+0

ダイナミックな名前を持つフレームではどうすればこのことができますか?私はフレームインデックス(例えば0または1)に頼ることができません。なぜなら、Twitterのようなソーシャルサービス(addtis経由)はしばしばバックグラウンドで独自のiframeに読み込まれるからです。 – DynamicDan

+0

フレーム名の代わりにフレームインデックスを使用できます - http://docs.casperjs.org/en/latest/modules/casper.html#withframe –

3

を使用することができ、我々は異なるフレーム(フレーム1を持っていると仮定frame2)、これらのフレームのさまざまな要素(divタグが終了するかどうかをクリックまたはチェックするなど)にアクセスする必要があります。

casper.withFrame('frame1', function() { 
    var file = '//*[@id="profile_file"]'; 
    casper.thenClick(x(file)); 
}); 

casper.withFrame('frame2', function() { 
    casper.then(function() { 
    casper.waitForSelector('#pageDIV', 
      function pass() { 
       console.log("pass"); 
      }, 
      function fail(){ 
       console.log("fail"); 
      } 
    ); 
    }); 
}); 
関連する問題