Scripted Browser 用スクリプトの書き方

Scripted Browsers は、Selenium [セレニウム]で強化された Google Chrome で動作する JavaScript ライクのスクリプト言語 [external link] を使います。このブラウザは、エミューレーターではありません。実際の完全な仮想化された Google Chrome です。例えば、https://docs.newrelic.com にアクセスし、その中で、tshirt を検索し、結果が表示されるまで待ち、表示された結果のリンクをクリックすることもできます。これを使えば、ウェブサイトが利用可能であることをチェックするだけでなく、ビジネスに重要なトランザクションが正しく動作していることさえも確認できるようになります。

Scripted Browser のサンプルは、New Relic のコミュニティフォーラムの Synthetics Scripts セクションにありますので、是非参考にしたり、シェアしてください。

Scripted Browser の概要

スクリプトを実行して動作するモニターは、Selenium の WebDriverJS を利用して行われます。API を使用して、実際のブラウザを通してサイトを監視するスクリプトを作成できます。スクリプトが実行されるたびに、Selenium 駆動の Google Chrome ブラウザを作成し、サイトへ移動し、スクリプトを順番に実行します。また、IDE スタイルのスクリプトエディタがあり、サジェスト機能やロケーター、その他、スクリプトを補助する機能を備えています。

このドキュメントでは、ある URL にアクセスするという基本的なスクリプトから始まり、ページ要素の検索操作の仕方を学びます。最後に、スクリプトが要素とインタラクションする前に、ページにその要素が存在していることを確認できるページ要素を待つ機能を紹介します。

スクリプトモニターの作成手順については、モニターの追加をご覧ください。また、Synthetics REST API を利用して Scripted Browser を追加する[英語]こともできます。利用可能な全機能については、Synthetics Scripted Browser リファレンスを参照してください。

実行時間が 3分を越えると、Syntheticsはスクリプトを手動で停止します。
screen-synthetics-scripting-ide.png
Synthetics > Add monitor > Scripted browser: スクリプトエディターは、関数、セレクター、その他の要素をサジェストします。

特定の URL へアクセス

すべてのスクリプトは、モニターがアクセスする URL を指定することから始めます。URL を指定するには、$browser.get("ここに URL を書く") を呼びます。

$browser.get("https://docs.newrelic.com");

連続したアクション

WebDriverJS は、非同期のため、スクリプトのアクションは、時々、順不同に実行されます。例えば、3つの関数を含むスクリプトがあったとして、3番目の関数が、2番目の関数の前に実行されることがあります。この実行順序を強制するには、以下のように、各アクションを then(function(){}) コールでラップします。

$browser.get("https://docs.newrelic.com").then(function(){
    return $browser.findElement($driver.By.linkText("Configuration Panel"));
});

複数のアクションを連続して、順番に実行するには、then(function(){}) コールを使って各アクションをラップして、別のコールをチェインしていきます。

$browser.get("https://docs.newrelic.com").then(function(){
    return $browser.findElement($driver.By.linkText("Configuration Panel"));
}).then(function(){
    return $browser.findElement($driver.By.partialLinkText("Configuration Pa"));
});

要素の検索

監視する URL を指定したら、次はページ上の特定の要素を探すでしょう。要素を検索することで、ページ上にその存在を確認し、ページ要素とインタラクションすることができます。

classidリンクのテキストname、XPath から要素を検索できます。利用する属性を見つけるには、ブラウザの開発者ツールを使ったり、サイトのソースコードから確認します。ロケーター関数の一覧は、ロケーター: ページ要素の検索をご覧ください。

class で検索

その HTML にある class をキーに要素を探します (例: class="button")。クラスは、通常、CSSスタイルに指定されています。クラスから要素を検索すると、モニターはそのクラスを持つページ内の最初の要素を選択します。

$browser.findElement($driver.By.className("button"));
ID で検索

正確な HTML の id をキーに要素を探します (例: id="edit-submit")。ページ要素を検索する方法としては非常に簡単な方法です。注意点として、変更されない id を指定してください。

$browser.findElement($driver.By.id("edit-submit"));

id で要素を検索する例は、サイトを検索をご覧ください。

表示されているリンクテキストをキーに要素を検索します。例えば、 in <a href="http://example.com>Your Link Text Here</a> におけるリンクテキストは、Your Link Text Here です。一致するリンクテキスト ($driver.By.linkText) や部分一致($driver.By.partialLinkText) で、検索できます。

$browser.findElement($driver.By.linkText("Configuration Panel"));
$browser.findElement($driver.By.partialLinkText("Configuration Pa"));

リンクテキストでリンクを検索する例は、リンク先に移動するをご覧ください。

name で検索

正確な name をキーに要素検索します (例: name="search-query-field")。検索窓などの入力フィールドで良く使われます。

$browser.findElement($driver.By.name("search-query-field"));

name で要素を検索する例は、ページ要素を待つをご覧ください。

XPath で検索

より複雑なページ構造の場合、要素の検索に、XPath が使えます。

$browser.findElement($driver.By.xpath("//input[@placeholder = 'search-query-field']"));

特定の要素探す XPath を簡単に見つけるには、以下のように Google Chrome の開発者ツールを使います。

  1. Chrome で、対象サイトを開く。
  2. 対象要素を右クリックし、Inspect Element を選択します。開発者ツールパネルが開き、対象の要素がハイライトされます。
  3. 開発者ツールパネルで、対象要素を右クリックし、Copy XPath [XPath をコピー]を選択します。

スクリプト内でこの XPath を使ってください。サイトが頻繁に更新されるような場合、ページ構造の変更によって XPath は変わる可能性があるため、モニターの失敗の原因に成る可能性があります。

要素とのインタラクション

スクリプトベースのモニターは、実際の Selenium で強化した Google Chrome で実行されます。ユーザーが実際に行うのと同じようにページの要素とインタラクションできます。例えば、モニターは、リンクのクリック、検索ボックスにテキストの入力など行うことができます。利用可能なアクション一覧については、ActionSequence: 複数アクションの連結をご覧ください。

初めに、ページ要素を探します。次に、インタラクション関数を呼び出します。

ページ要素をクリックする

リンクや他のページ要素をクリックするには、ページ要素を見つけ、click() 関数を呼び出します。

$browser.findElement($driver.By.linkText("Configuration Panel")).click();
$browser.findElement($driver.By.className("config-panel-02")).click();

見つけた要素をクリックする例は、サイトを検索するにもあります。

doubleClick() [ダブルクリック], dragAndDrop() [ドラッグ&ドロップ]、mouseDown [マウスダウン]、mouseUp [マウスアップ]、mouseMove [マウス移動]といったマウス操作に関する関数も使えます。
テキストを入力する

フィールドにテキストを入力するには、フィールドを見つけ、sendKeys() 関数を呼び出します。

$browser.findElement($driver.By.name("search-query-field")).sendKeys("EXAMPLE USER NAME");
$browser.findElement($driver.By.id("search-q-box")).sendKeys("EXAMPLE USER NAME");

フィールドによっては、デフォルドでテキストが入力されている場合があります。その場合は、以下のように最初にフィールドをクリアしてから、テキストを入力してください。

$browser.findElement($driver.By.name("search-query-field")).clear();
$browser.findElement($driver.By.id("search-q-box")).clear();

フィールドにテキストを入力する例は、サイトにログインするでも見れます。

keyDown()keyUp() 関数で、修飾キー(ALTSHIFT など) を追加できます。

待ちとタイムアウト

画像や複雑で動的なコンテキストのような巨大なページ要素の読み込みに長時間かかる時があります。これにより、モニターがインタラクションしようとしたり、まだ読み込まれていない要素を見つける処理が失敗することがあります。

この問題を避けるには、その要素が表示されるまで、スクリプトを一時停止する待ち条件を記述する必要があります。この条件の一覧は、条件: 一時停止と待ちの条件で見ることができます。

ページタイトルを待つ

特定の値と一致するページタイトルの表示を待つ指示を、モニターに出します。これにより、ブラウザは少なくとも対象ページから、データを受信して​​いることを保証します。ページタイトルを待つ関数の呼び出しには、期待するタイトルとタイムアウト値(ミリ秒単位)を指定します。

//wait 関数の呼び出し
$browser.wait(function() {
//ページタイトルを取得し、そのタイトルを使って関数を実行する
Tell the monitor to get the page title, then run a function on that title.
  return $browser.getTitle().then(function(title) {
//期待するページタイトルを指定する
    return title === "Your Page Title Here";
    });
// 1000 ミリ秒(1秒)以内に条件を満たさない場合は、次の処理に移動する
}, 1000);

ページタイトルを待つスクリイプトの例は、ページの読み込みを待つでも確認できます。

特定の要素を待つ

あるページ要素の表示を待つ指示を、モニターに出します。これは特定の要素がロードに時間がかかったり,その要素をクリックする前に、ページ要素が存在することを確認したりする場合に役立ちます。

以下のように wait 関数で locate 関数を使用することもできます。以下で使用している $driver.By.linkText 関数の代わりに好きな関数を使用できます。

//   7,500 ミリ秒 (7.5 秒) まで待つ
Tell the monitor to wait up to 7,500 milliseconds (7.5 seconds) for a link whose text is `Your Link Text Here`.
$browser.waitForElement($driver.By.linkText("Your Link Text Here"), 7500);

特定の要素の読み込みを待つスクリプトの例は、ページ要素を待つで見ることができます。

また、アクション順番に実行することもできます。待ち関数は、スクリプトの実行前に、ページ要素が存在することを保証します。一方、連続したアクションでは、各要素が(並列実行ではなく)順番に実行されることを保証します。

解析サービスのブロック解除

Synthetics は、デフォルトで、実行中、有名な解析サービスのスクリプトをブロックします。サービスを指定して、スクリプトの許可することができます。そうすることで、サービスのスクリプトを実行し、実際のユーザーと同様の挙動でデータを収集することができます。

//Google Analytics スクリプトの実行を許可
$browser.addHostnameToWhitelist(hostnameArr: ['google-analytics.com']);

//https://docs.newrelic.com にアクセス
$browser.get('https://docs.newrelic.com');

スクリプトの結果をログに記録

モニターの結果をスクリプトのログに記録できます。
この機能は、スクリプトのデバッグに便利です。各キーとなるステップでログ関数を呼び出すことで、スクリプトのどの段階で失敗したかを発見できます。

静的なテキストを記録する

静的なテキストをログに記録するには、console.log() 関数を呼び出します。

//コンソールログに、`That's one small step for man.` を送る
console.log('That\'s one small step for man.');

これは、以下のように出力されます。

// ----------------------------------- コンソールログ
That's one small step for man.
変数をログ関数に渡す

静的なテキストを記録するだけでなく、console.log() に変数を渡すこともできます。

//`WEBSITE_URL` 変数の定義
var assert = require('assert'),
  WEBSITE_URL = 'https://docs.newrelic.com/';

console.log('That\'s one small step for man.');
//`WEBSITE_URL` に指定したサイトを読み込む
$browser.get(WEBSITE_URL);
//コンソールに成功を記録する
console.log('One giant leap for', WEBSITE_URL);

これは、以下のように出力されます。

// ----------------------------------- コンソールログ
That's one small step for man.
One giant leap for https://docs.newrelic.com/

追加モジュールのインポート

Node.js で人気の多くのモジュールをインポートすることができます。これにより、テストデータを自動で登録したり、複雑な関数をシンプルにしたりでき、テストをより強化できます。詳しくは、Node.js モジュールのインポートをご覧ください。

関連情報

関連する情報は以下のとおりです。