20190811のReactに関する記事は4件です。

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 が求められていなくてもローカルに用意することが多々あるので、少しでも自動化できるのは嬉しいですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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をクリックします。

image.png

今回はGitHubからのデプロイなので、GitHubを選択します。
image.png

デプロイするレポジトリで作成したブログのレポジトリを選択します。

image.png

次の画面でDeploy siteをクリックする事でデプロイが始まります。

image.png

デプロイができたら、サイトを確認してみましょう。
ここでは https://elastic-montalcini-5361d7.netlify.comがサイトのURLになります。

image.png

URLの変更

URLが気にくわない場合は Site settings をクリックし、Change Site namenetlify.com以前のURLを変更する事が出来ます。
また、カスタムドメインを使用することも出来ます。

デプロイ後のブログの更新

Neflifyではmasterブランンチにコミットやマージがあると自動的にデプロイが走り、ブログが更新されます。
ですので、記事を追加したり、デザインを変更した後に、GitHubでmasterブランチにその変更をプッシュするだけでサイトの更新が可能です。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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にデプロイしていることもあり,ブランチを雑に弄ったりするのはやだな〜と思っていたので,簡単に解決できて良かったですね.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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もっとメジャーになれ(なれ)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む