最近、IE 8 で Bad HTML の解釈が他のブラウザーと違ってて、プログラムが動かなくなったことが発見しました。
基本的に、あってはいけないことですが、<script></script> の中に、他の <script> tag が定義されて、W3C の標準に違反になりますが、ブラウザーは自分の解釈で実行できてますけど、どうやら、この場合、IE 8 だけ、</div> が追加されるそうです。。。
W3C の標準とブラウザーの実装は基本的に同じですので、</script> という close tag を探して、script の終了をわかるようになります。もし <script> の中に他の <script> tag を入れたら、このルールが破れますので、どのように実行するかはブラウザーに任せます。。。
これで、最新のブラウザー (IE9 ~) は問題なく、正確な HTML と同じように解釈しますけど、 IE8 は独自のルールに従います。。。
まぁ、IE 8 の使用率はもう 2% 以下だから、直さなくてもいいと思います。
それでは。
Code
2014年12月2日火曜日
2014年11月20日木曜日
IE 11 userAgent 変更
今日、隣のチームが変なバグを遭遇しました。一般的には IE8 では動かないバグがよくありますが、今回は IE11 で editor が動かなくなりました。具体的に言うと、chrome などのブラウザーでは、rich text editor が自動的に生成されますが、IE 11 では普通の textarea になっていました。
ちょっと調べてみたら、なぜか、iframe が生成されるコードが実行しなくなりました。もう少し確認したら、IE 11 はサポートブラザー外になりました。
コードを追ってみると、userAgent を取得して、"MSIE" をチェックして、IE のバージョンを確認する処理がありました。IE 11 では MSIE という文字列がなくなったことが発見しました。
へ〜、本当に起こりました。。。こういうことは。
以前予想していましたが、実際起こるのですね。userAgent でブラウザーを判断することはよくないと以前から話してましたが、まだいろいろライブラリーがそれを使ってますね。。。
まぁ、ブラウザーの userAgent は相変わらずごちゃごちゃですけど。。。
今回は rv:11.0 からバージョンは取得できるので、それをコードに追加して、うまくいきました。。。ただ、他のスクリプットエラーが出て。。。
x-ua-compatible を EmulateIE9 に追加したら、実行できました。。。
なんでだろうね。。。
MS も IE 11 をおしているようです。面白いサイトです:
http://www.rethinkie.com/hello-again/#/intro
ちょっと調べてみたら、なぜか、iframe が生成されるコードが実行しなくなりました。もう少し確認したら、IE 11 はサポートブラザー外になりました。
コードを追ってみると、userAgent を取得して、"MSIE" をチェックして、IE のバージョンを確認する処理がありました。IE 11 では MSIE という文字列がなくなったことが発見しました。
へ〜、本当に起こりました。。。こういうことは。
以前予想していましたが、実際起こるのですね。userAgent でブラウザーを判断することはよくないと以前から話してましたが、まだいろいろライブラリーがそれを使ってますね。。。
まぁ、ブラウザーの userAgent は相変わらずごちゃごちゃですけど。。。
今回は rv:11.0 からバージョンは取得できるので、それをコードに追加して、うまくいきました。。。ただ、他のスクリプットエラーが出て。。。
x-ua-compatible を EmulateIE9 に追加したら、実行できました。。。
なんでだろうね。。。
MS も IE 11 をおしているようです。面白いサイトです:
http://www.rethinkie.com/hello-again/#/intro
2014年11月9日日曜日
protractor コマンドラインと補助ツール
基本的に、protractor の config js ファイルにあるものはそのままコマンドラインにパラメーターを書けば、上書きできます。常用のものは
--baseUrl="NEW URL" <- これでテスト対象の URL が変更できます。テストケースの中に browser.baseUrl から取得可能です。
--params.xxx.xxx=NEW VALUE <- もし、config js に pramas フィールドが追加されるなら、params の値を送れば、NEW VALUE が適用されます。
もし、一つだけのテストケースを実行したいなら、
--suites=SUITE NAME
--specs=TEST CASE FILE NAME
で、ターゲットスイート、テストケースファイルが実行できます。複数実行したい場合、 コマで区切れば、protractor がそのまま実行できます。
テスト結果のレポートは HTML バージョンは下記のライブラリをつかれば、簡単につくれます。スクリーンショット付きで。
package/protractor-html-screenshot-reporter
config js ファイルの onprepare 関数に Jasmine の reporter を設定すれば、自動でフォルダに HTML と画面キャプチャーが作成されます。
あと、selenium sever をサーバーのものを使いたいなら、
--seleniumAddress を使えば、どこかのサーバーアドレスに設定できます。localhost じゃなくて。
注意すべきところは、リモートサーバーを使いたいなら、タイムアウト時間をちょっと長めに設定したほうがいいです。
これも Jasmine のものと合わせて、config js ファイルに
allScriptsTimeout: 30000 <- WebDriver の script タイムアウト時間を 30 秒に設定
jasmineNodeOpts: {defaultTimeoutInterval: 30000} <- Jasmine timeout を 30秒に設定
あと、ページタイムアウト、これを browser.get(url, time) 第二の引数に設定するも可能です。
getPageTimeout:30000
どのブラウザーでテストするには、capabilities, multi-capabilities で設定できるので、注意は一つ。
IE の場合、IEDriver の問題で 64bit が超遅いです。IE 11も対応してないので、IE10 + 32bit driver を使えば、回避できます。
record&play ツールとして、firefox には selenium builder を使えば、protractor js フォーマットのテストケースはそのままできますので。活用すれば、時間の節約に。
selenium builder
ただ、できたケースはコードはあまり良くないし、select には作成できないので、これを locator の element(by.options()), by.repeater で自分で書くしかないです。
それでは、また。
--baseUrl="NEW URL" <- これでテスト対象の URL が変更できます。テストケースの中に browser.baseUrl から取得可能です。
--params.xxx.xxx=NEW VALUE <- もし、config js に pramas フィールドが追加されるなら、params の値を送れば、NEW VALUE が適用されます。
もし、一つだけのテストケースを実行したいなら、
--suites=SUITE NAME
--specs=TEST CASE FILE NAME
で、ターゲットスイート、テストケースファイルが実行できます。複数実行したい場合、 コマで区切れば、protractor がそのまま実行できます。
テスト結果のレポートは HTML バージョンは下記のライブラリをつかれば、簡単につくれます。スクリーンショット付きで。
package/protractor-html-screenshot-reporter
config js ファイルの onprepare 関数に Jasmine の reporter を設定すれば、自動でフォルダに HTML と画面キャプチャーが作成されます。
あと、selenium sever をサーバーのものを使いたいなら、
--seleniumAddress を使えば、どこかのサーバーアドレスに設定できます。localhost じゃなくて。
注意すべきところは、リモートサーバーを使いたいなら、タイムアウト時間をちょっと長めに設定したほうがいいです。
これも Jasmine のものと合わせて、config js ファイルに
allScriptsTimeout: 30000 <- WebDriver の script タイムアウト時間を 30 秒に設定
jasmineNodeOpts: {defaultTimeoutInterval: 30000} <- Jasmine timeout を 30秒に設定
あと、ページタイムアウト、これを browser.get(url, time) 第二の引数に設定するも可能です。
getPageTimeout:30000
どのブラウザーでテストするには、capabilities, multi-capabilities で設定できるので、注意は一つ。
IE の場合、IEDriver の問題で 64bit が超遅いです。IE 11も対応してないので、IE10 + 32bit driver を使えば、回避できます。
record&play ツールとして、firefox には selenium builder を使えば、protractor js フォーマットのテストケースはそのままできますので。活用すれば、時間の節約に。
selenium builder
ただ、できたケースはコードはあまり良くないし、select には作成できないので、これを locator の element(by.options()), by.repeater で自分で書くしかないです。
それでは、また。
ローカル Web App : AngularJS + ExpressJS + Node.js
先週、検証チームから依頼があって、protractor を UI で動くようにしたいと。確かに、コマンドラインはちょっと使いづらいので。慣れてる人は、それでいいかもしれないけど、テスターはやはり、もうちょっとビジュアル的な UI や、テストケースレポートが欲しがるようです。
いろいろ考えてみると、protractor も Node.js で動かしているので、そのまま Node を使えるなら、HTML 5 の Web App を作れば、簡単に UI ができるし、NodeJS の力を使って、コマンドラインを実行すれば、早くできると思われました。
実際調べて見たら、Express.js と Hapi.js みたいなライブラリーがあって、web server もすぐ立てられそうです。また将来、コードをそのまま使って、どこかのサーバに置いたら、同じ UI で、すぐ Online できるので、メリットが大きいです。
それで、AngularJS を Front End で、Express.js を Back End にして、ツールを作ることになりました。インストールは npm で済ませて、Yeoman, bower で AngularJS のアップを作って、grunt でビルドなども立てて、すぐ開発に入りました。
Express.js に generator がついてるので、それを使って、Back End のアプリも簡単に立ち上がりました。
$ npm install express-generator -g
$ express myapp
下記のフォルダストラクチャーができました。app.js に path に基づいて、get, post などを書けば簡単には response 作れるようになります。static ファイルを front end に送るには、 sendfi le 関数を使えば、protractor のテスト結果レポートも簡単に Front End で表示できる。
いろいろ考えてみると、protractor も Node.js で動かしているので、そのまま Node を使えるなら、HTML 5 の Web App を作れば、簡単に UI ができるし、NodeJS の力を使って、コマンドラインを実行すれば、早くできると思われました。
実際調べて見たら、Express.js と Hapi.js みたいなライブラリーがあって、web server もすぐ立てられそうです。また将来、コードをそのまま使って、どこかのサーバに置いたら、同じ UI で、すぐ Online できるので、メリットが大きいです。
それで、AngularJS を Front End で、Express.js を Back End にして、ツールを作ることになりました。インストールは npm で済ませて、Yeoman, bower で AngularJS のアップを作って、grunt でビルドなども立てて、すぐ開発に入りました。
Express.js に generator がついてるので、それを使って、Back End のアプリも簡単に立ち上がりました。
$ npm install express-generator -g
$ express myapp
下記のフォルダストラクチャーができました。app.js に path に基づいて、get, post などを書けば簡単には response 作れるようになります。static ファイルを front end に送るには、 sendfi le 関数を使えば、protractor のテスト結果レポートも簡単に Front End で表示できる。
.
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade
7 directories, 9 files
さらに、もし興味があれば、 MEAN.js というライブラリがあるので
mean.js
MangoDBをデータベースとして、フル JavaScript のアプリも簡単につくれます。
Meteor も有名です。そのまま iPhone, Android アプリも作れるので、どんどん良くなっています。
それでは。
2014年10月31日金曜日
IE8 AngularJS & jQuery ui - problem -> ng-non-bindable の使い方
昨日、隣のチームから変なバグが聞かれました。具体的に、jQuery ui の datepicker が IE8 では動かなくなった。まぁ、最新版の AngularJS は IE8 サポートしてないから、問題ないけど、今のプロジェクトでは 1.0.8 を使ってるし、IE8 もサポート対象ブラウザーなので。。。あ〜頭が痛くなる。。。
jQuery の datepicker のサープルを IE8 で開いて、動きは正しいようです。多分、AngularJS と jQuery ui の間に何か干渉が起きたと思われました。HTML を見てみたら、各日付の <td> tag 中の <a> に <!-- IE fix --> コメントが追加されたことが気づきました。AngularJS には <a> tag を IE8 での特別処理が入ってるようです。
// add a comment node to anchors to workaround IE bug that causes element content to be reset
// to new attribute content if attribute is updated with value containing @ and element also
// contains value with @
// see issue #1949
jQuery の datepicker のサープルを IE8 で開いて、動きは正しいようです。多分、AngularJS と jQuery ui の間に何か干渉が起きたと思われました。HTML を見てみたら、各日付の <td> tag 中の <a> に <!-- IE fix --> コメントが追加されたことが気づきました。AngularJS には <a> tag を IE8 での特別処理が入ってるようです。
// add a comment node to anchors to workaround IE bug that causes element content to be reset
// to new attribute content if attribute is updated with value containing @ and element also
// contains value with @
// see issue #1949
つまり、AngularJS は上記の IE fix コメントを追加したのです。一般的なライブラリは innerHTML を使って、タグの内容を取得すると、その IE fix も一緒に取得されるのです。parseInt などを使うと、エクセプションが throw されます。本来数字のみ入っている場所に他の文字列が入ったので、何か起きると、不思議ではない。
もう少し調べてみたら、Angular は ng-non-bindable という directive を提供しています。これを使うと、 Angular は HTML DOM をスキャンする時、そのブロックをスキップさせます。つまりその中にある要素は Angular の $digest サイクルに入らない。
これで、Angular は勝手に <a> tag 何かを入れることがなくなります。問題解決。
今後 IE 8 をサポートしている間、気をつけないと。
それでは。
2014年10月18日土曜日
Protractor での自動テスト
先週から、検証チームを助けて、Protractor での自動テストが始めました。先日ダウンロードして、インストールしようと思ったんですけど、npm がなぜかshanum エラーが出ました。調べたら、ネットワークのせいかもしれないと、もう一回インストールして、無事成功しました。
Protractor を動かすには、まず Selenium サーバーを起動して、config ファイルにそのアドレスと、spec の場所を入れて、後、Jasmine sytax での spec が必要です。
Protractor とともに、webdriver-manager と言う Node のコマンドがインストールされます。webdriver-manager update を実行すると、google から chromedriver.exe, IEserverdriver.exeと、Selenium jar ファイルがダウンロードされます。その後、webdriver-manager start で selenium サーバーが起動されます。Jetty なんちゃら 4444 がコンソールに表示されたら、起動成功。
その後、config に下記の JSON を記入して、spec を書いて、すぐ実行できるようになります。
注意すべきところは、protractor は selenium のラッバーみたいなもので、AngularJS 終了を待ってから、コマンドを実行してます。(おそらく、Angular の phase をチェックしてるかもしれない)、もし、ウェブページに Angular がなければ、変なエラーが出るのです。原因は protractor ずっと待ってて、待ち続けて、タイムアウトになります。
このとき、browser.get や element などが使えなくなります。browser.driver を使うべきです。browser.driver は webdriver js で、findElement などが使えます。この時、適当に sleep を入れて、JS の実行完了や、ajax の実行などを自分でまつ必要になります。。。
やはり、protractor が使いやすいですね。
後日、また続きを。それでは。
Protractor を動かすには、まず Selenium サーバーを起動して、config ファイルにそのアドレスと、spec の場所を入れて、後、Jasmine sytax での spec が必要です。
Protractor とともに、webdriver-manager と言う Node のコマンドがインストールされます。webdriver-manager update を実行すると、google から chromedriver.exe, IEserverdriver.exeと、Selenium jar ファイルがダウンロードされます。その後、webdriver-manager start で selenium サーバーが起動されます。Jetty なんちゃら 4444 がコンソールに表示されたら、起動成功。
その後、config に下記の JSON を記入して、spec を書いて、すぐ実行できるようになります。
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['todo-spec.js']
};
spec のサンプル:describe('angularjs homepage todo list', function() {
it('should add a todo', function() {
browser.get('http://www.angularjs.org');
element(by.model('todoText')).sendKeys('write a protractor test');
element(by.css('[value="add"]')).click();
var todoList = element.all(by.repeater('todo in todos'));
expect(todoList.count()).toEqual(3); browser.sleep(3000);
expect(todoList.get(2).getText()).toEqual('write a protractor test');
});
});
protractor conf.js を実行すれば、angular のウェブページが表示されて、TODO に自動的に一つアイテムを追加されて、その後、 TODO の数をチェックして、終了。注意すべきところは、protractor は selenium のラッバーみたいなもので、AngularJS 終了を待ってから、コマンドを実行してます。(おそらく、Angular の phase をチェックしてるかもしれない)、もし、ウェブページに Angular がなければ、変なエラーが出るのです。原因は protractor ずっと待ってて、待ち続けて、タイムアウトになります。
このとき、browser.get や element などが使えなくなります。browser.driver を使うべきです。browser.driver は webdriver js で、findElement などが使えます。この時、適当に sleep を入れて、JS の実行完了や、ajax の実行などを自分でまつ必要になります。。。
やはり、protractor が使いやすいですね。
後日、また続きを。それでは。
Android WebView の 動画が遅い件
先日、新しい Ads のパフォーマンスが良くないなと思っただけで、今日は他のチームも発見して、相談されました。具体的には WebView を使って、HTML ファイルを表示してますが、画像では iOS, Android 両方問題なく、良く表示されてますが、動画の場合、ある Android 機器が超遅くて、遅くて、使い物になれないほどです。
実際、Web Inspect で見てみると、JS の実行が遅いです。じゃ、 CSS ではどうでしょうと思って、ほぼすべてのコードを書き換えて、CSS でアニメーションを実現して、試しました。。。でも、遅いです。。。CSSの場合、ハードウェアの加速があるので、速いと言われていますが、Android ではそうではないそうです。まぁ、機器のスペクもよるので、Nexus 5 で試しましたが、iOS ほどスムーズではないですが、そこそこ動いています。
こう見ると、多分古い Android 機器はだめみたいです。。。何でだろうと思って、やはり WebView はブラウザーより遅くて、開発時は注意しないと。
一応メモして、将来何か参考になるかもしれないです。
それでは。
実際、Web Inspect で見てみると、JS の実行が遅いです。じゃ、 CSS ではどうでしょうと思って、ほぼすべてのコードを書き換えて、CSS でアニメーションを実現して、試しました。。。でも、遅いです。。。CSSの場合、ハードウェアの加速があるので、速いと言われていますが、Android ではそうではないそうです。まぁ、機器のスペクもよるので、Nexus 5 で試しましたが、iOS ほどスムーズではないですが、そこそこ動いています。
こう見ると、多分古い Android 機器はだめみたいです。。。何でだろうと思って、やはり WebView はブラウザーより遅くて、開発時は注意しないと。
一応メモして、将来何か参考になるかもしれないです。
それでは。
登録:
投稿 (Atom)