- 投稿日:2019-08-11T13:27:06+09:00
WebdriverIO でファイルの添付・ペースト・ドロップをテストする
行うにあたって少し調べる時間を取られたよくある三種のテストをまとめました。
WebdriverIO は v5 です。
画像の添付・ペースト・ドロップを行うと img タグで表示するので、正しく表示されているかを検査するテストを想定しています。
input[type="file"]
にファイルを添付する
$(selector).click()
によりファイル選択ダイアログは表示できますが、Webdriver からそれを操作することができません。そこでしかるべきメソッドを使用する必要があります。
v5
ではchooseFile
の替わりにbrowser.uploadFile
+$(selector).setValue(remoteFile)
の組みあわせで添付を実現します。describe('attach file', () => { const attachment = '[data-role="attach_file"]'; const addedImage = '[data-role="added_image"]'; const filePath = path.join(__dirname, '../../fixtures/100_150.png'); const expectedSize = { width: 100, height: 150 }; it('attach', async () => { browser.url('https://codepen.io/mmmpa/pen/mNzqpP'); browser.switchToFrame(0); const remoteFilePath = browser.uploadFile(filePath); $(attachment).setValue(remoteFilePath); assert.deepEqual($(addedImage).getSize(), expectedSize); }); });クリップボード上のなにかをペーストする
任意のローカル上のファイルをペーストしたい場合は、環境に応じた clipboard 操作コマンドを使ってデータを登録し、ペーストします。
わたしは Debian を使用しているので
xclip
を使用しました。describe('paste file', () => { const pasteZone = '[data-role="paste_zone"]'; const addedImage = '[data-role="added_image"]'; const filePath = path.join(__dirname, '../../fixtures/100_150.png'); const expectedSize = { width: 100, height: 150 }; it('paste', async () => { browser.url('https://codepen.io/mmmpa/pen/bXmYvr'); browser.switchToFrame(0); $(pasteZone).click(); exec(`xclip -i -selection clipboard -t image/png < ${filePath}`) browser.keys(["Control", "v"]) assert.deepEqual($(addedImage).getSize(), expectedSize); }); });ファイルをドロップする
残念ながら画面外のファイルをドロップする方法は見つかりませんでした。(OS を操作すれば可能かもしれません)
そこでフェイクイベントを作成して
dispatchEvent
し、それを以て動作の確認を行います。フェイクイベントが持つためのファイルの転送には先述のuploadFile
を使用します。なお
React
を使用している場合は普通のdispatchEvent
には反応しないため、ReactTestUtils.Simulate.drop
を使用する必要がありました。共通部分: ファイル転送処理
browser.addCommand
で任意のメソッドを登録できるので、ファイル転送用のメソッドを登録します。
input[type="file"]
にファイルを添付し、それを後ほど作成するフェイクイベントに持たせます。返り値は selector と除去用の関数です。const { v4 } = require('uuid') browser.addCommand("prepareFileContainer", function (filePath) { const elementID = `new${v4()}`; const selector = `#${elementID}`; this.execute(` var input = document.createElement('input'); input.setAttribute('id', '${elementID}'); input.setAttribute('type', 'file'); document.body.appendChild(input); `); const remoteFilePath = this.uploadFile(filePath); $(selector).setValue(remoteFilePath); this.execute(` var input = document.querySelector('${selector}'); var items = Array.from(input.files).map(f => ({ kind: 'file', getAsFile: () => f})); input.items = items; `); const clear = () => this.execute(` var input = document.querySelector('${selector}'); document.body.removeChild(input); `); return [selector, clear]; });普通の DOM 用のイベント発行メソッド登録
フェイクイベントを作成しペーストされる DOM にイベントを発行する処理をメソッドとして登録します。
browser.addCommand("dropFile", function (targetSelector, filePath) { const [selector, clear] = this.prepareFileContainer(filePath); this.execute(` var items = document.querySelector('${selector}').items; var event = new Event('drop'); event.dataTransfer = { items: items } document.querySelector('${targetSelector}').dispatchEvent(event); `); clear(); });React DOM 用のイベント発行メソッド登録
ReactTestUtils
を使用するためにグローバルな位置に宣言しなければならなかったので (https://codepen.io/mmmpa/pen/JgmreB) 、なにか正しい方法をご存知の方はご教示いただけると幸いです。browser.addCommand("dropFileToReact", function (targetSelector, filePath) { const [selector, clear] = this.prepareFileContainer(filePath); this.execute(` var items = document.querySelector('${selector}').items; ReactTestUtils.Simulate.drop( document.querySelector('${targetSelector}'), { dataTransfer: { items: items } } ); `); clear(); });テスト本体
登録済みのメソッドを用いてペーストを擬似的に再現し、動作を確認します。
describe('drop file', () => { const dropZone = '[data-role="drop_zone"]'; const addedImage = '[data-role="added_image"]'; const filePath = path.join(__dirname, '../../fixtures/100_150.png'); const expectedSize = { width: 100, height: 150 }; it('plain textarea', async () => { browser.url('https://codepen.io/mmmpa/pen/voVLQR'); browser.switchToFrame(0); browser.dropFile(dropZone, filePath); assert.deepEqual($(addedImage).getSize(), expectedSize); }); it('react textarea', async () => { browser.url('https://codepen.io/mmmpa/pen/JgmreB'); browser.switchToFrame(0); browser.dropFileToReact(dropZone, filePath, true); assert.deepEqual($(addedImage).getSize(), expectedSize); }); });おわりに
ファイル周りのテストは手作業で行うのは辛い面があります。私の場合 e2e が求められていなくてもローカルに用意することが多々あるので、少しでも自動化できるのは嬉しいですね。
- 投稿日:2019-08-11T10:37:18+09:00
【5分でデプロイまで】Gatsbyで爆速ブログを作成
概要
Gatsbyのスターターと、Netlifyを使用して誰でも5分で爆速ブログを作成する方法を紹介します。
記事内ではこちらのブログをデプロイまで行います。
Gatsbyとは?
Gatsbyに関してはこの方の記事でとても良く説明されています。
Gatsbyのインストール
Gatsbyがインストールされていない場合は以下のコマンドでインストールしましょう。
$ npm install -g gatsby-cliブログの作成
以下のコマンドでブログを作成します。
my-blog
の部分でブログの名前を指定します。https://github.com/gatsbyjs/gatsby-starter-blog
の箇所は使用するスターターを指定します。こちらから好きなデザインを選ぶ事が可能です。
$ gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-blogローカルで確認
作成したブログのディレクトリに移動し、ローカルでブログを確認しましょう。
以下のコマンドを実行すると、
http://localhost:8000/
でブログが起動している事が確認できます。$ cd my-new-blog $ gatsby develop新しい記事の追加
content/blog
に新しいマークダウンファイル(.md
)を追加してみましょう。
すると、自動でブログに記事が更新されている事が確認できます。--- title: テスト記事 --- 今日はいい天気だな。ブログをGitHubにプッシュする。
Netlifyを使用したデプロイ方法ではデプロイしたいサイトがGitHub/GitLab/Bitbucketで管理されている必要があります。
本記事ではGitHubを使用します。git init git add . git commit -m "Initial commit"git remote add origin https://github.com/yourname/your-blog-name.git git push -u origin masterブログをデプロイする
Netlifyのアカウントがない場合は作成しましょう。
アカウント作成後、以下のNew site from Git
をクリックします。今回はGitHubからのデプロイなので、GitHubを選択します。
デプロイするレポジトリで作成したブログのレポジトリを選択します。
次の画面で
Deploy site
をクリックする事でデプロイが始まります。デプロイができたら、サイトを確認してみましょう。
ここではhttps://elastic-montalcini-5361d7.netlify.com
がサイトのURLになります。URLの変更
URLが気にくわない場合は
Site settings
をクリックし、Change Site name
でnetlify.com
以前のURLを変更する事が出来ます。
また、カスタムドメインを使用することも出来ます。デプロイ後のブログの更新
Neflifyではmasterブランンチにコミットやマージがあると自動的にデプロイが走り、ブログが更新されます。
ですので、記事を追加したり、デザインを変更した後に、GitHubでmasterブランチにその変更をプッシュするだけでサイトの更新が可能です。参考
- 投稿日:2019-08-11T01:34:48+09:00
create-react-appで作ったReactアプリケーションがローカルサーバでしか動かない
どうしたの
Reactでアプリケーションを作っている時に,ディレクトリ構成をごにょごにょしてローカルサーバで動作することを確認, そのままデプロイしたら本番環境で画面が真っ白になっていました.
デプロイ先はgithub pagesのサーバです.
なんだこれと思いながら色々調べるのに時間がかかったのでメモしておきます.
原因
ビルドにwebpackを使っているんですが,webpackがビルドする時に相対パス指定をぶっ壊してしまっているっぽいことが原因みたい.
ただ,create-react-appだとwebpackの設定をいじれないのでここで難儀しました.
解決法
アプリケーションのルートディレクトリに
jsconfig.json
というファイルを作成して,そこにビルド時の設定を記述することで解決できました.記述は以下のような感じです.React関連のJavaScriptファイルがsrcディレクトリ以下に存在することを仮定しています.
jsconfig.json{ "compilerOptions": { "target": "es2015", "baseUrl": "./src/" } }まとめ
github pagesにデプロイしていることもあり,ブランチを雑に弄ったりするのはやだな〜と思っていたので,簡単に解決できて良かったですね.
- 投稿日:2019-08-11T01:25:21+09:00
Reactでp5を使ってたらWarning: You must first call texture() before using vertex() with image based u and v coordinatesが出た
なんやこいつ
React-p5-Wrapperを使ってReactでp5のコンポーネントを作って遊んでいたら,drow()が呼ばれるたびに下記のようなwarningがGoogle ChromeのConsoleに出ていました.
console.You must first call texture() before using vertex() with image based u and v coordinatesこいつのせいでConsoleがめちゃ重だし,パフォーマンスにも影響を与えてそうなので解決しました.
解決法
こちらを参考にすると,どうやら使っているp5.jsのバージョンが悪いことに起因してそう.
確認してみるとreact-p5-wrapperが依存しているp5.jsのバージョンが7.3.4でした.
というわけで,node_modulesの中にいるであろうp5のバージョンをあげます(Reactアプリケーションなので).terminal.yarn upgrade p5@0.9.0 --saveこれで解決!!
まとめ
p5もっとメジャーになれ(なれ)