DOM Storage の デバッグ用ブックマークレット

HTML5DOM Storage とか DOM ストレージ とか Web Storage とか localStorage とか言われてるヤツ
Cookie よりも使い勝手の良い、ブラウザローカルにデータ保存出来るんだけど、Cookie の用にブラウザの機能で中身を確認したり消したり出来ない(よね?)なので、一覧表示と全削除だけですが、出来るブックマークレットを作ったので一応アップする。(自分用)


以下のリンクをずるずるブックマークの欄に持って行くと良いでしょう。

っと思ったら、JavaScript のコードのリンクは張れなさそうなのでコードだけ・・・
適当にブックマークを作成して、名前付けて、urlに以下のコードを貼り付ければOKです。


localStorage表示

javascript:(function(){ls=window.localStorage;s="Count="+ls.length+"\n";for(i=0;i

localStorage全削除

javascript:(function(){ls=window.localStorage;while(ls.length>0){ls.removeItem(ls.key(0));}})();

当然、表示や削除しているのはブックマークレットを実行したときに表示しているページに対してです。

Firefox 3.0.11 で DOMストレージの動きがおかしい

前振り

Wassrで色々と Greasemonkey(以下グリモン) 書いてる訳なのですが、設定を保存したいグリモンが有って、設定データをCookieに保存していたのですが、利用者次第でデータの量がふくれてCookieのサイズ(4K)を超えてしまい、400 BadRequest になると言う根本の問題を抱えていた欠陥グリモンでした。
で、Cookieの変わりに DOMストレージはどうよ?って教えてもらって試して見たのが事の始まり。

DOMストレージの状況

DOMストレージはCookieを使わずにローカル側にデータをハッシュ形式で保存できる仕組みで localStorageオブジェクトを利用します。(※セッション期間だけ有効な、sessionStorageもあります)
Firefox 3.0.11 ではまだ未実装で、代わりに同様の globalStorage オブジェクトを使う事で同じ機能を実現する(はずでした)。
参照 -> DOM Storage - DOM | MDN


IE8 と Safari4 に関しては HTML5仕様の localStorageオブジェクトが実装済みで動きます。

問題

グリモンを作っていて気付いたのですが、Firefox の DOMストレージが複数タブ間で上手く同期されていないようなのです。
で、単純な検証ページを作成して確認する事にしました。

検証ページ(コード)

検証ページは A と B があります。検証ページへのリンク -> 検証ページA 検証ページB
各々のページには「追加処理」「全削除」「全表示」ボタンと、DOMストレージの内容を表示する textarea が存在します。
両ページの動きは同じで、「追加処理」を行ったときの追加するデータが違います。


ページAは
Key[ADD] に対して、"AAA," を追加します。
Key[KeyAAA] に対して、"ValueAAA" をセットします。


ページBは
Key[ADD] に対して、"BBB," を追加します。
Key[KeyBBB] に対して、"ValueBBB" をセットします。


「全削除」は DOMストレージの中身をハッシュのキーを走査して全部消します。
「全表示」は現在のDOMストレージの中身を表示します。


localStorageが使えるブラウザ(IE8とSafari4)はlocalStorageを、localStorageの無いFirefoxでは globalStorageを使うようになってます。

	var ls = window.localStorage || window.globalStorage[location.hostname];

再現方法と現象と・・・

以下の表は上から時系列に進めていく過程での、実行コマンドとストレージの内容を示しています。
検証は、Firefox 3.0.11 にて


列説明

A処理
検証ページAでの実施した処理
B処理
検証ページBでの実施した処理
A状態
検証ページAで左記処理後にDOMストレージの内容「全表示」押下して表示した結果。
B状態
検証ページBで左記処理後にDOMストレージの内容「全表示」押下して表示した結果。
想定結果
想定(希望される)される結果(Safari4とIE8での結果と同様)


状態は [キー]=値 の形式で書きます。

ケース1

A処理 B処理 A状態 B状態 想定結果
1 OPEN - 無し 無し 無し
2 - OPEN 無し 無し 無し
3 「追加処理」押下 - [ADD]=AAA,
[KeyAAA]=ValueAAA
無し(※アレ?) [ADD]=AAA,
[KeyAAA]=ValueAAA
4 - 「追加処理」押下 [ADD]=AAA,BBB,
[KeyAAA]=ValueAAA
(※アレ?)
[ADD]=AAA,BBB,
[KeyAAA]=ValueAAA
[KeyBBB]=ValueBBB
[ADD]=AAA,BBB,
[KeyAAA]=ValueAAA
[KeyBBB]=ValueBBB
5 「追加処理」押下 - [ADD]=AAA,BBB,AAA
[KeyAAA]=ValueAAA
[KeyBBB]=ValueBBB
[ADD]=AAA,BBB,AAA
[KeyAAA]=ValueAAA
[KeyBBB]=ValueBBB
[ADD]=AAA,BBB,AAA
[KeyAAA]=ValueAAA
[KeyBBB]=ValueBBB
6 - 「全削除」押下 [ADD]=
[KeyAAA]=
[KeyBBB]=
(※アレ?)
無し 無し
7 「全削除」押下
->スクリプトハング
- [ADD]=
[KeyAAA]=
[KeyBBB]=
(※アレ?)
無し 無し
8 CLOSE - 無し 無し 無し

この後、表示するとキーも消えてるw


ケース2

A処理 B処理 A状態 B状態 想定結果
1 OPEN - 無し 無し 無し
2 - OPEN 無し 無し 無し
3 「追加処理」押下 - [ADD]=AAA,
[KeyAAA]=ValueAAA
無し(※アレ?) [ADD]=AAA,
[KeyAAA]=ValueAAA
4 CLOSE - × 無し(※アレ?) [ADD]=AAA,
[KeyAAA]=ValueAAA
5 - CLOSE × × [ADD]=AAA,
[KeyAAA]=ValueAAA
6 OPEN - [ADD]=AAA,
[KeyAAA]=ValueAAA
× [ADD]=AAA,
[KeyAAA]=ValueAAA
7 - OPEN [ADD]=AAA,
[KeyAAA]=ValueAAA
[ADD]=AAA,
[KeyAAA]=ValueAAA
[ADD]=AAA,
[KeyAAA]=ValueAAA


なんですかねコレ?汗


他にも色々と変な状態にはなったのですが、上記で十分かと・・・コレって一体・・・Firefoxより自分を疑いたいのですが・・・IE8とSafari4は想定通りに動いてくれたので・・・

label ロケーターの追加と、フォーカスの有る Element を取得するアクセサー(?)の追加

label には for 属性が有って、関連している Element を指定できる。
で、その label をクリックすると関連している Element にフォーカスが移る。

<label for="text_to">Text:</label> <input type="text" id="text_to" name="text_to">

とかしておくと、 Text: って label をクリックすると text_to ってテキストボックスにフォースが移る訳ね。
で、その試験もあって・・・Selenium で label を簡単に指定できる Element locator が無かったので作った。


user-extensions.js に追加

PageBot.prototype.locateElementByLabel = function(text, inDocument ){
  var labels = inDocument.getElementsByTagName('label');
  for (var i = 0; i < labels.length; i++) {
    var element = labels[i];
    if (PatternMatcher.matches(text, getText(element))) {
      return element;
    }
  }
  return null;
};


ってしておくと

<tr>
  <td>click</td>
  <td>label=Text:</td>
  <td></td>
</tr>

ってすると、Text: って label をクリックしたことになります〜(あんまり用途は無いと思うけど・・・)


で、クリックされてテキストボックスにフォーカスが移った確認もしないといけないので・・・フォーカスがどこにあるのか調べる方法は


フォーカスされている要素を取得する方法 - sawatのブログ


に、有ったんですけど Firefox でうまくいきません。記事が古くて Firefox がその時の物と違うからかな〜っと。
まあ、IE でやるので気にせずそのまま流用してコードを書く!


user-extensions.js に追加

Selenium.prototype.isFocus = function( locator ){

  var element1 = (this.page().getDocument().activeElement || this.page().getCurrentWindow().getSelection().focusNode); // IE & Opera || Firefox
  var element2 = this.browserbot.findElement(locator);

  return element1 == element2;
};


ってしておくと

<tr>
  <td>verifyFocus</td>
  <td>name=text_to</td>
  <td>true</td>
</tr>

とかで、フォーカスの有無をチェックできまする。


Firefox でフォーカスの有るオブジェクトを取得する方法って無いのかな〜


Selenium って拡張しやすいので便利やわ〜♪

Selenium IDE と accesskey と ショートカット

単体試験項目で、accesskey の指定と指定されたキーのショートカットを使ったことで、指定された Element に飛ぶか(押されるか)を確認する項目がある。

<input type="button" value="ぼたん" name="btn" accesskey="s">

って、ボタンが有ったとしよう。


IE だと、Alt + s 、firefox だと Alt + Shift + s で name=btn が押されるんだけど。


Selenium IDE で覚えさせると、ボタンを押したという結果だけが記録されて、ショートカットを使ってボタンを押したという事象(?)が記録されない。


Selenium IDE の覚え方

<tr>
  <td>click</td>
  <td>//input[@value='ぼたん']<td>
  <td></td>
</tr>


覚えて欲しい形(ショットカットを使ってボタンを押したという形)

<tr>
  <td>altKeyDown</td>
  <td></td>
  <td></td>
</tr>
<tr>
  <td>keyPress</td>
  <td>※謎1</td>
  <td>s</td>
</tr>
<tr>
  <td>altKeyUp</td>
  <td></td>
  <td></td>
</tr>


って感じ。


※謎1の部分が謎なので Selenium IDE で確認しようと思ったんだけどね・・・分からないままです。
別にどこの locator とか無いんだよね〜キーを押す対象は・・・


ショートカットキーを押して、アクションがありましたよって確認を Selenium でしたい。
どうやるんだ?継続調査中・・・


あっ、accesskey 属性が正しく設定されているかっていうのは、veriftAttribute とかで試験できるのは分かってるので・・・分かった上で、キー操作をエミュレートしてショートカットキーを使ったという試験がしたい。

Alert のスクリーンショット取りたいんだけどね〜無理なの?

alert が表示されるのは、 assertAlert とかで確認できるのよ。
スクリーンショットも取得できるのよ。


ただ、assertAlert で alert を捕獲してしまうと、実際には alert のダイアログ出ないのよね〜
alert のダイアログが出ている状態でスクリーンショット撮りたいのよね・・・


でも、alert ダイアログ出ちゃったら・・・ JavaScript から OK ボタンとか押下出来ないよね?
だから、alert ダイアログが出てる状態のスクリーンショット無理かな?っと半ばあきらめかけ・・・


なにか、勘違いか手段があるのかも知れないのでかいとく。
解決法何かありましたらご教授ください。

Selenium Core 0.7.0から0.8.3で増えたの減ったの

差分調べてので書いておきます。
詳細は調べていませんが、利用者は名前で何となく分かると思います。w

  • Element Locators(増加)
  • Selenium Actions(増加)
    • Selenium Actions
    • allowNativeXpath
    • altKeyDown
    • altKeyUp
    • assignId
    • break
    • chooseOkOnNextConfirmation
    • clickAt
    • controlKeyDown
    • controlKeyUp
    • createCookie
    • deleteCookie
    • doubleClick
    • doubleClickAt
    • dragAndDrop
    • dragAndDropToObject
    • dragdrop
    • echo
    • getSpeed
    • highlight
    • metaKeyDown
    • metaKeyUp
    • mouseDownAt
    • mouseMove
    • mouseMoveAt
    • mouseOut
    • mouseUp
    • mouseUpAt
    • openWindow
    • pause
    • removeAllSelections
    • runScript
    • selectFrame
    • setBrowserLogLevel
    • setCursorPosition
    • setMouseSpeed
    • setSpeed
    • shiftKeyDown
    • shiftKeyUp
    • store
    • typeKeys
    • waitForFrameToLoad
    • windowFocus
    • windowMaximize
  • Selenium Accessors(増加)
    • assertErrorOnNext
    • assertFailureOnNext
    • assertSelected
    • storeAllWindowIds
    • storeAllWindowNames
    • storeAllWindowTitles
    • storeAttributeFromAllWindows
    • storeCookie
    • storeCursorPosition
    • storeElementHeight
    • storeElementIndex
    • storeElementPositionLeft
    • storeElementPositionTop
    • storeElementWidth
    • storeMouseSpeed
    • storeSelectedId
    • storeSelectedIds
    • storeSelectedIndex
    • storeSelectedIndexes
    • storeSelectedLabel
    • storeSelectedLabels
    • storeSelectedValue
    • storeSelectedValues
    • storeWhetherThisFrameMatchFrameExpression
    • storeWhetherThisWindowMatchWindowExpression
    • storeXpathCount
    • storeOrdered
    • storeSomethingSelected
  • Selenium Accessors(減少)
    • storeAbsoluteLocation
    • storeSelected
    • storeSelectedOptions


です。
減少は細分化されて置き換わった物がほとんどのような気がします。


詳細は英語リファレンス参照してください。w