From e1dac618a8b8929f601c7ec8aca3842c5ebf9d03 Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka <ueokande@i-beam.org>
Date: Mon, 13 Apr 2020 20:37:36 +0900
Subject: Use plugin:prettier/recommended

---
 .../components/form/SearchEngineForm.test.tsx      | 165 ++++++++++++---------
 1 file changed, 97 insertions(+), 68 deletions(-)

(limited to 'test/settings/components/form/SearchEngineForm.test.tsx')

diff --git a/test/settings/components/form/SearchEngineForm.test.tsx b/test/settings/components/form/SearchEngineForm.test.tsx
index b918203..ccbd197 100644
--- a/test/settings/components/form/SearchEngineForm.test.tsx
+++ b/test/settings/components/form/SearchEngineForm.test.tsx
@@ -1,35 +1,42 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import ReactTestRenderer from 'react-test-renderer';
-import ReactTestUtils from 'react-dom/test-utils';
-import SearchForm from 'settings/components/form/SearchForm'
-import { FormSearch } from 'shared/SettingData';
+import React from "react";
+import ReactDOM from "react-dom";
+import ReactTestRenderer from "react-test-renderer";
+import ReactTestUtils from "react-dom/test-utils";
+import SearchForm from "settings/components/form/SearchForm";
+import { FormSearch } from "shared/SettingData";
 
 describe("settings/form/SearchForm", () => {
-  describe('render', () => {
-    it('renders SearchForm', () => {
-      const root = ReactTestRenderer.create(<SearchForm value={FormSearch.fromJSON({
-        default: 'google',
-        engines: [['google', 'google.com'], ['yahoo', 'yahoo.com']],
-      })} />).root;
+  describe("render", () => {
+    it("renders SearchForm", () => {
+      const root = ReactTestRenderer.create(
+        <SearchForm
+          value={FormSearch.fromJSON({
+            default: "google",
+            engines: [
+              ["google", "google.com"],
+              ["yahoo", "yahoo.com"],
+            ],
+          })}
+        />
+      ).root;
 
-      const names = root.findAllByProps({ name: 'name' });
+      const names = root.findAllByProps({ name: "name" });
       expect(names).to.have.lengthOf(2);
-      expect(names[0].props.value).to.equal('google');
-      expect(names[1].props.value).to.equal('yahoo');
+      expect(names[0].props.value).to.equal("google");
+      expect(names[1].props.value).to.equal("yahoo");
 
-      const urls = root.findAllByProps({ name: 'url' });
+      const urls = root.findAllByProps({ name: "url" });
       expect(urls).to.have.lengthOf(2);
-      expect(urls[0].props.value).to.equal('google.com');
-      expect(urls[1].props.value).to.equal('yahoo.com');
+      expect(urls[0].props.value).to.equal("google.com");
+      expect(urls[1].props.value).to.equal("yahoo.com");
     });
   });
 
-  describe('onChange event', () => {
+  describe("onChange event", () => {
     let container;
 
     beforeEach(() => {
-      container = document.createElement('div');
+      container = document.createElement("div");
       document.body.appendChild(container);
     });
 
@@ -38,72 +45,94 @@ describe("settings/form/SearchForm", () => {
       container = null;
     });
 
-    it('invokes onChange event on edit', (done) => {
+    it("invokes onChange event on edit", (done) => {
       ReactTestUtils.act(() => {
-        ReactDOM.render(<SearchForm
-          value={FormSearch.fromJSON({
-            default: 'google',
-              engines: [['google', 'google.com'], ['yahoo', 'yahoo.com']]
-          })}
-          onChange={value => {
-            const json = value.toJSON();
-            expect(json.default).to.equal('louvre');
-            expect(json.engines).to.have.lengthOf(2)
-            expect(json.engines).to.have.deep.members(
-              [['louvre', 'google.com'], ['yahoo', 'yahoo.com']]
-            );
-            done();
-          }} />, container);
+        ReactDOM.render(
+          <SearchForm
+            value={FormSearch.fromJSON({
+              default: "google",
+              engines: [
+                ["google", "google.com"],
+                ["yahoo", "yahoo.com"],
+              ],
+            })}
+            onChange={(value) => {
+              const json = value.toJSON();
+              expect(json.default).to.equal("louvre");
+              expect(json.engines).to.have.lengthOf(2);
+              expect(json.engines).to.have.deep.members([
+                ["louvre", "google.com"],
+                ["yahoo", "yahoo.com"],
+              ]);
+              done();
+            }}
+          />,
+          container
+        );
       });
 
-      const radio = document.querySelectorAll('input[type=radio]');
+      const radio = document.querySelectorAll("input[type=radio]");
       radio.checked = true;
 
-      const name = document.querySelector('input[name=name]');
-      name.value = 'louvre';
+      const name = document.querySelector("input[name=name]");
+      name.value = "louvre";
 
       ReactTestUtils.Simulate.change(name);
     });
 
-    it('invokes onChange event on delete', (done) => {
+    it("invokes onChange event on delete", (done) => {
       ReactTestUtils.act(() => {
-        ReactDOM.render(<SearchForm value={FormSearch.fromJSON({
-            default: 'yahoo',
-            engines: [['louvre', 'google.com'], ['yahoo', 'yahoo.com']]
-          })}
-          onChange={value => {
-            const json = value.toJSON();
-            expect(json.default).to.equal('yahoo');
-            expect(json.engines).to.have.lengthOf(1)
-            expect(json.engines).to.have.deep.members(
-              [['yahoo', 'yahoo.com']]
-            );
-            done();
-          }} />, container);
+        ReactDOM.render(
+          <SearchForm
+            value={FormSearch.fromJSON({
+              default: "yahoo",
+              engines: [
+                ["louvre", "google.com"],
+                ["yahoo", "yahoo.com"],
+              ],
+            })}
+            onChange={(value) => {
+              const json = value.toJSON();
+              expect(json.default).to.equal("yahoo");
+              expect(json.engines).to.have.lengthOf(1);
+              expect(json.engines).to.have.deep.members([
+                ["yahoo", "yahoo.com"],
+              ]);
+              done();
+            }}
+          />,
+          container
+        );
       });
 
-      const button = document.querySelector('input[type=button]');
+      const button = document.querySelector("input[type=button]");
       ReactTestUtils.Simulate.click(button);
     });
 
-    it('invokes onChange event on add', (done) => {
+    it("invokes onChange event on add", (done) => {
       ReactTestUtils.act(() => {
-        ReactDOM.render(<SearchForm value={FormSearch.fromJSON({
-          default: 'yahoo',
-            engines: [['google', 'google.com']]
-          })}
-          onChange={value => {
-            const json = value.toJSON();
-            expect(json.default).to.equal('yahoo');
-            expect(json.engines).to.have.lengthOf(2)
-            expect(json.engines).to.have.deep.members(
-              [['google', 'google.com'], ['', '']],
-            );
-            done();
-          }} />, container);
+        ReactDOM.render(
+          <SearchForm
+            value={FormSearch.fromJSON({
+              default: "yahoo",
+              engines: [["google", "google.com"]],
+            })}
+            onChange={(value) => {
+              const json = value.toJSON();
+              expect(json.default).to.equal("yahoo");
+              expect(json.engines).to.have.lengthOf(2);
+              expect(json.engines).to.have.deep.members([
+                ["google", "google.com"],
+                ["", ""],
+              ]);
+              done();
+            }}
+          />,
+          container
+        );
       });
 
-      const button = document.querySelector('input[type=button].ui-add-button');
+      const button = document.querySelector("input[type=button].ui-add-button");
       ReactTestUtils.Simulate.click(button);
     });
   });
-- 
cgit v1.2.3


From b0fe06bc2e739cc252a559f666da65b27769959d Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka <ueokande@i-beam.org>
Date: Wed, 15 Apr 2020 19:35:15 +0900
Subject: Fix types in tests

---
 .../infrastructures/MemoryStorage.test.ts          |  9 +--
 test/background/repositories/Mark.test.ts          |  9 +--
 test/background/usecases/parsers.test.ts           |  3 +-
 test/console/actions/console.test.ts               |  8 +++
 .../console/components/console/Completion.test.tsx | 50 ++++++++------
 test/console/reducers/console.test.ts              | 76 ++++++++++++++--------
 test/content/InputDriver.test.ts                   |  2 -
 test/content/presenters/Hint.test.ts               | 10 +--
 .../content/presenters/NavigationPresenter.test.ts |  8 ++-
 test/content/usecases/SettingUseCaase.test.ts      |  4 +-
 test/main.ts                                       |  5 --
 .../components/form/BlacklistForm.test.tsx         | 38 +++++++----
 test/settings/components/form/KeymapsForm.test.tsx |  9 +--
 .../components/form/PropertiesForm.test.tsx        | 18 +++--
 .../components/form/SearchEngineForm.test.tsx      | 24 ++++---
 test/settings/components/ui/input.test.tsx         | 32 ++++-----
 test/settings/reducers/setting.test.ts             | 51 ++++++++-------
 test/shared/operations.test.ts                     | 13 ++--
 18 files changed, 221 insertions(+), 148 deletions(-)

(limited to 'test/settings/components/form/SearchEngineForm.test.tsx')

diff --git a/test/background/infrastructures/MemoryStorage.test.ts b/test/background/infrastructures/MemoryStorage.test.ts
index 5f8be2a..1c67b18 100644
--- a/test/background/infrastructures/MemoryStorage.test.ts
+++ b/test/background/infrastructures/MemoryStorage.test.ts
@@ -1,4 +1,5 @@
-import MemoryStorage from "background/infrastructures/MemoryStorage";
+import MemoryStorage from "../../../src/background/infrastructures/MemoryStorage";
+import { expect } from "chai";
 
 describe("background/infrastructures/memory-storage", () => {
   it("stores values", () => {
@@ -29,12 +30,12 @@ describe("background/infrastructures/memory-storage", () => {
 
   it("stored cloned objects", () => {
     const cache = new MemoryStorage();
-    const recipe = { sugar: "300g" };
+    const recipe = { sugar: "300g", salt: "10g" };
     cache.set("recipe", recipe);
 
     recipe.salt = "20g";
-    const got = cache.get("recipe", recipe);
-    expect(got).to.deep.equal({ sugar: "300g" });
+    const got = cache.get("recipe");
+    expect(got).to.deep.equal({ sugar: "300g", salt: "10g" });
   });
 
   it("throws an error with unserializable objects", () => {
diff --git a/test/background/repositories/Mark.test.ts b/test/background/repositories/Mark.test.ts
index b1bbcf1..5cee5b6 100644
--- a/test/background/repositories/Mark.test.ts
+++ b/test/background/repositories/Mark.test.ts
@@ -1,4 +1,5 @@
-import MarkRepository from "background/repositories/MarkRepository";
+import MarkRepository from "../../../src/background/repositories/MarkRepository";
+import { expect } from "chai";
 
 describe("background/repositories/mark", () => {
   let repository: MarkRepository;
@@ -10,15 +11,15 @@ describe("background/repositories/mark", () => {
   it("get and set", async () => {
     const mark = { tabId: 1, url: "http://example.com", x: 10, y: 30 };
 
-    repository.setMark("A", mark);
+    await repository.setMark("A", mark);
 
-    let got = await repository.getMark("A");
+    let got = (await repository.getMark("A"))!!;
     expect(got.tabId).to.equal(1);
     expect(got.url).to.equal("http://example.com");
     expect(got.x).to.equal(10);
     expect(got.y).to.equal(30);
 
-    got = await repository.getMark("B");
+    got = (await repository.getMark("B"))!!;
     expect(got).to.be.undefined;
   });
 });
diff --git a/test/background/usecases/parsers.test.ts b/test/background/usecases/parsers.test.ts
index bee0d07..019b56e 100644
--- a/test/background/usecases/parsers.test.ts
+++ b/test/background/usecases/parsers.test.ts
@@ -1,4 +1,5 @@
-import * as parsers from "background/usecases/parsers";
+import * as parsers from "../../../src/background/usecases/parsers";
+import { expect } from "chai";
 
 describe("shared/commands/parsers", () => {
   describe("#parsers.parseSetOption", () => {
diff --git a/test/console/actions/console.test.ts b/test/console/actions/console.test.ts
index 5a531a6..3169c4b 100644
--- a/test/console/actions/console.test.ts
+++ b/test/console/actions/console.test.ts
@@ -2,7 +2,15 @@ import * as actions from "../../../src/console/actions";
 import * as consoleActions from "../../../src/console/actions/console";
 import { expect } from "chai";
 
+// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
+// @ts-ignore
+import browserFake from "webextensions-api-fake";
+
 describe("console actions", () => {
+  beforeEach(() => {
+    (global as any).browser = browserFake();
+  });
+
   describe("hide", () => {
     it("create CONSOLE_HIDE action", () => {
       const action = consoleActions.hide();
diff --git a/test/console/components/console/Completion.test.tsx b/test/console/components/console/Completion.test.tsx
index 200bb1a..921720b 100644
--- a/test/console/components/console/Completion.test.tsx
+++ b/test/console/components/console/Completion.test.tsx
@@ -1,6 +1,9 @@
 import React from "react";
-import Completion from "console/components/console/Completion";
-import ReactTestRenderer from "react-test-renderer";
+import Completion from "../../../../src/console/components/console/Completion";
+import ReactTestRenderer, { ReactTestInstance } from "react-test-renderer";
+import { expect } from "chai";
+import CompletionTitle from "../../../../src/console/components/console/CompletionTitle";
+import CompletionItem from "../../../../src/console/components/console/CompletionItem";
 
 describe("console/components/console/completion", () => {
   const completions = [
@@ -24,13 +27,22 @@ describe("console/components/console/completion", () => {
 
   it("renders Completion component", () => {
     const root = ReactTestRenderer.create(
-      <Completion completions={completions} size={30} />
+      <Completion completions={completions} size={30} select={-1} />
     ).root;
 
-    expect(root.children).to.have.lengthOf(1);
-
-    const children = root.children[0].children;
+    // const children = root.findByType('ul').children as Array<ReactTestInstance>;
+    const children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children).to.have.lengthOf(8);
+    expect(children.map((e) => e.type)).to.deep.equal([
+      CompletionTitle,
+      CompletionItem,
+      CompletionItem,
+      CompletionItem,
+      CompletionTitle,
+      CompletionItem,
+      CompletionItem,
+      CompletionItem,
+    ]);
     expect(children[0].props.title).to.equal("Fruit");
     expect(children[1].props.caption).to.equal("apple");
     expect(children[2].props.caption).to.equal("banana");
@@ -46,7 +58,7 @@ describe("console/components/console/completion", () => {
       <Completion completions={completions} size={30} select={3} />
     ).root;
 
-    const children = root.children[0].children;
+    const children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children[5].props.highlight).to.be.true;
   });
 
@@ -55,10 +67,8 @@ describe("console/components/console/completion", () => {
       <Completion completions={completions} size={30} select={-1} />
     ).root;
 
-    const children = root.children[0].children;
-    for (const li of children[0].children) {
-      expect(li.props.highlight).not.to.be.ok;
-    }
+    const children = root.findByType("ul").findAllByType(CompletionItem);
+    expect(children.every((e) => e.props.highlight === false)).to.be.true;
   });
 
   it("limits completion items", () => {
@@ -66,7 +76,7 @@ describe("console/components/console/completion", () => {
       <Completion completions={completions} size={3} select={-1} />
     ).root;
 
-    let children = root.children[0].children;
+    let children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children).to.have.lengthOf(3);
 
     expect(children[0].props.title).to.equal("Fruit");
@@ -77,7 +87,7 @@ describe("console/components/console/completion", () => {
       <Completion completions={completions} size={3} select={0} />
     ).root;
 
-    children = root.children[0].children;
+    children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children[1].props.highlight).to.be.true;
   });
 
@@ -87,7 +97,7 @@ describe("console/components/console/completion", () => {
     );
     const root = component.root;
 
-    let children = root.children[0].children;
+    let children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children).to.have.lengthOf(3);
     expect(children[0].props.title).to.equal("Fruit");
     expect(children[1].props.caption).to.equal("apple");
@@ -97,7 +107,7 @@ describe("console/components/console/completion", () => {
       <Completion completions={completions} size={3} select={2} />
     );
 
-    children = root.children[0].children;
+    children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children).to.have.lengthOf(3);
     expect(children[0].props.caption).to.equal("apple");
     expect(children[1].props.caption).to.equal("banana");
@@ -108,7 +118,7 @@ describe("console/components/console/completion", () => {
       <Completion completions={completions} size={3} select={3} />
     );
 
-    children = root.children[0].children;
+    children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children).to.have.lengthOf(3);
     expect(children[0].props.caption).to.equal("cherry");
     expect(children[1].props.title).to.equal("Element");
@@ -122,7 +132,7 @@ describe("console/components/console/completion", () => {
     );
     const root = component.root;
 
-    let children = root.children[0].children;
+    let children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children).to.have.lengthOf(3);
     expect(children[0].props.caption).to.equal("argon");
     expect(children[1].props.caption).to.equal("boron");
@@ -132,21 +142,21 @@ describe("console/components/console/completion", () => {
       <Completion completions={completions} size={3} select={4} />
     );
 
-    children = root.children[0].children;
+    children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children[1].props.highlight).to.be.true;
 
     component.update(
       <Completion completions={completions} size={3} select={3} />
     );
 
-    children = root.children[0].children;
+    children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children[0].props.highlight).to.be.true;
 
     component.update(
       <Completion completions={completions} size={3} select={2} />
     );
 
-    children = root.children[0].children;
+    children = root.findByType("ul").children as Array<ReactTestInstance>;
     expect(children[0].props.caption).to.equal("cherry");
     expect(children[1].props.title).to.equal("Element");
     expect(children[2].props.caption).to.equal("argon");
diff --git a/test/console/reducers/console.test.ts b/test/console/reducers/console.test.ts
index e8432c5..64e8eb3 100644
--- a/test/console/reducers/console.test.ts
+++ b/test/console/reducers/console.test.ts
@@ -1,9 +1,12 @@
-import * as actions from "console/actions";
-import reducer from "console/reducers";
+import * as actions from "../../../src/console/actions";
+import reducer, { State } from "../../../src/console/reducers";
+import { expect } from "chai";
+import CompletionType from "../../../src/shared/CompletionType";
+import { ConsoleAction } from "../../../src/console/actions";
 
 describe("console reducer", () => {
   it("return the initial state", () => {
-    const state = reducer(undefined, {});
+    const state = reducer(undefined, {} as any);
     expect(state).to.have.property("mode", "");
     expect(state).to.have.property("messageText", "");
     expect(state).to.have.property("consoleText", "");
@@ -12,68 +15,85 @@ describe("console reducer", () => {
   });
 
   it("return next state for CONSOLE_HIDE", () => {
-    const action = { type: actions.CONSOLE_HIDE };
-    const state = reducer({ mode: "error" }, action);
+    const initialState = reducer(undefined, {} as any);
+    const action: actions.ConsoleAction = { type: actions.CONSOLE_HIDE };
+    const state = reducer({ ...initialState, mode: "error" }, action);
     expect(state).to.have.property("mode", "");
   });
 
   it("return next state for CONSOLE_SHOW_COMMAND", () => {
-    const action = { type: actions.CONSOLE_SHOW_COMMAND, text: "open " };
-    const state = reducer({}, action);
+    const action: actions.ConsoleAction = {
+      type: actions.CONSOLE_SHOW_COMMAND,
+      completionTypes: [CompletionType.SearchEngines, CompletionType.History],
+      text: "open ",
+    };
+    const state = reducer(undefined, action);
     expect(state).to.have.property("mode", "command");
     expect(state).to.have.property("consoleText", "open ");
   });
 
   it("return next state for CONSOLE_SHOW_INFO", () => {
-    const action = { type: actions.CONSOLE_SHOW_INFO, text: "an info" };
-    const state = reducer({}, action);
+    const action: actions.ConsoleAction = {
+      type: actions.CONSOLE_SHOW_INFO,
+      text: "an info",
+    };
+    const state = reducer(undefined, action);
     expect(state).to.have.property("mode", "info");
     expect(state).to.have.property("messageText", "an info");
   });
 
   it("return next state for CONSOLE_SHOW_ERROR", () => {
-    const action = { type: actions.CONSOLE_SHOW_ERROR, text: "an error" };
-    const state = reducer({}, action);
+    const action: actions.ConsoleAction = {
+      type: actions.CONSOLE_SHOW_ERROR,
+      text: "an error",
+    };
+    const state = reducer(undefined, action);
     expect(state).to.have.property("mode", "error");
     expect(state).to.have.property("messageText", "an error");
   });
 
   it("return next state for CONSOLE_HIDE_COMMAND", () => {
-    const action = { type: actions.CONSOLE_HIDE_COMMAND };
-    let state = reducer({ mode: "command" }, action);
+    const initialState = reducer(undefined, {} as any);
+    const action: actions.ConsoleAction = {
+      type: actions.CONSOLE_HIDE_COMMAND,
+    };
+    let state = reducer({ ...initialState, mode: "command" }, action);
     expect(state).to.have.property("mode", "");
 
-    state = reducer({ mode: "error" }, action);
+    state = reducer({ ...initialState, mode: "error" }, action);
     expect(state).to.have.property("mode", "error");
   });
 
   it("return next state for CONSOLE_SET_CONSOLE_TEXT", () => {
-    const action = {
+    const action: actions.ConsoleAction = {
       type: actions.CONSOLE_SET_CONSOLE_TEXT,
       consoleText: "hello world",
     };
-    const state = reducer({}, action);
+    const state = reducer(undefined, action);
 
     expect(state).to.have.property("consoleText", "hello world");
   });
 
   it("return next state for CONSOLE_SET_COMPLETIONS", () => {
-    let state = {
+    const initialState = reducer(undefined, {} as any);
+    let state: State = {
+      ...initialState,
       select: 0,
       completions: [],
     };
-    const action = {
+    const action: actions.ConsoleAction = {
       type: actions.CONSOLE_SET_COMPLETIONS,
       completions: [
         {
           name: "Apple",
-          items: [1, 2, 3],
+          items: [{}, {}, {}],
         },
         {
           name: "Banana",
-          items: [4, 5, 6],
+          items: [{}, {}, {}],
         },
       ],
+      completionSource: "",
     };
     state = reducer(state, action);
     expect(state).to.have.property("completions", action.completions);
@@ -81,17 +101,19 @@ describe("console reducer", () => {
   });
 
   it("return next state for CONSOLE_COMPLETION_NEXT", () => {
-    const action = { type: actions.CONSOLE_COMPLETION_NEXT };
+    const initialState = reducer(undefined, {} as any);
+    const action: ConsoleAction = { type: actions.CONSOLE_COMPLETION_NEXT };
     let state = {
+      ...initialState,
       select: -1,
       completions: [
         {
           name: "Apple",
-          items: [1, 2],
+          items: [{}, {}],
         },
         {
           name: "Banana",
-          items: [3],
+          items: [{}],
         },
       ],
     };
@@ -110,17 +132,19 @@ describe("console reducer", () => {
   });
 
   it("return next state for CONSOLE_COMPLETION_PREV", () => {
-    const action = { type: actions.CONSOLE_COMPLETION_PREV };
+    const initialState = reducer(undefined, {} as any);
+    const action: ConsoleAction = { type: actions.CONSOLE_COMPLETION_PREV };
     let state = {
+      ...initialState,
       select: -1,
       completions: [
         {
           name: "Apple",
-          items: [1, 2],
+          items: [{}, {}],
         },
         {
           name: "Banana",
-          items: [3],
+          items: [{}],
         },
       ],
     };
diff --git a/test/content/InputDriver.test.ts b/test/content/InputDriver.test.ts
index bfada87..f464dac 100644
--- a/test/content/InputDriver.test.ts
+++ b/test/content/InputDriver.test.ts
@@ -16,8 +16,6 @@ describe("InputDriver", () => {
 
   afterEach(() => {
     target.remove();
-    target = null;
-    driver = null;
   });
 
   it("register callbacks", (done) => {
diff --git a/test/content/presenters/Hint.test.ts b/test/content/presenters/Hint.test.ts
index e64c39f..f961f88 100644
--- a/test/content/presenters/Hint.test.ts
+++ b/test/content/presenters/Hint.test.ts
@@ -13,17 +13,17 @@ describe("Hint", () => {
 
   describe("#constructor", () => {
     it("creates a hint element with tag name", () => {
-      const link = document.getElementById("test-link");
+      const link = document.getElementById("test-link")!!;
       new Hint(link, "abc");
 
       const elem = document.querySelector(".vimvixen-hint");
-      expect(elem.textContent.trim()).to.be.equal("abc");
+      expect(elem!!.textContent!!.trim()).to.be.equal("abc");
     });
   });
 
   describe("#show", () => {
     it("shows an element", () => {
-      const link = document.getElementById("test-link");
+      const link = document.getElementById("test-link")!!;
       const hint = new Hint(link, "abc");
       hint.hide();
       hint.show();
@@ -46,10 +46,10 @@ describe("Hint", () => {
 
   describe("#remove", () => {
     it("removes an element", () => {
-      const link = document.getElementById("test-link");
+      const link = document.getElementById("test-link")!!;
       const hint = new Hint(link, "abc");
 
-      const elem = document.querySelector(".vimvixen-hint");
+      const elem = document.querySelector(".vimvixen-hint")!!;
       expect(elem.parentElement).to.not.be.null;
       hint.remove();
       expect(elem.parentElement).to.be.null;
diff --git a/test/content/presenters/NavigationPresenter.test.ts b/test/content/presenters/NavigationPresenter.test.ts
index b362d8d..af3b487 100644
--- a/test/content/presenters/NavigationPresenter.test.ts
+++ b/test/content/presenters/NavigationPresenter.test.ts
@@ -4,7 +4,7 @@ import { expect } from "chai";
 describe("NavigationPresenterImpl", () => {
   let sut: NavigationPresenterImpl;
 
-  const testRel = (done, rel, html) => {
+  const testRel = (done: () => void, rel: string, html: string) => {
     const method =
       rel === "prev" ? sut.openLinkPrev.bind(sut) : sut.openLinkNext.bind(sut);
     document.body.innerHTML = html;
@@ -14,8 +14,10 @@ describe("NavigationPresenterImpl", () => {
       done();
     }, 0);
   };
-  const testPrev = (html) => (done) => testRel(done, "prev", html);
-  const testNext = (html) => (done) => testRel(done, "next", html);
+  const testPrev = (html: string) => (done: () => void) =>
+    testRel(done, "prev", html);
+  const testNext = (html: string) => (done: () => void) =>
+    testRel(done, "next", html);
 
   before(() => {
     sut = new NavigationPresenterImpl();
diff --git a/test/content/usecases/SettingUseCaase.test.ts b/test/content/usecases/SettingUseCaase.test.ts
index 19a167a..1cc1e8a 100644
--- a/test/content/usecases/SettingUseCaase.test.ts
+++ b/test/content/usecases/SettingUseCaase.test.ts
@@ -40,7 +40,7 @@ describe("AddonEnabledUseCase", () => {
   let sut: SettingUseCase;
 
   beforeEach(() => {
-    const testSettings = {
+    const testSettings = Settings.fromJSON({
       keymaps: {},
       search: {
         default: "google",
@@ -54,7 +54,7 @@ describe("AddonEnabledUseCase", () => {
         complete: "sbh",
       },
       blacklist: [],
-    };
+    });
 
     repository = new MockSettingRepository();
     client = new MockSettingClient(testSettings);
diff --git a/test/main.ts b/test/main.ts
index 8097975..fded23a 100644
--- a/test/main.ts
+++ b/test/main.ts
@@ -1,6 +1 @@
 import "reflect-metadata";
-import { expect } from "chai";
-import browserFake from "webextensions-api-fake";
-
-global.expect = expect;
-global.browser = browserFake();
diff --git a/test/settings/components/form/BlacklistForm.test.tsx b/test/settings/components/form/BlacklistForm.test.tsx
index 4d79383..e34802a 100644
--- a/test/settings/components/form/BlacklistForm.test.tsx
+++ b/test/settings/components/form/BlacklistForm.test.tsx
@@ -6,6 +6,7 @@ import { expect } from "chai";
 
 import BlacklistForm from "../../../../src/settings/components/form/BlacklistForm";
 import Blacklist from "../../../../src/shared/settings/Blacklist";
+import AddButton from "../../../../src/settings/components/ui/AddButton";
 
 describe("settings/form/BlacklistForm", () => {
   describe("render", () => {
@@ -16,26 +17,32 @@ describe("settings/form/BlacklistForm", () => {
         />
       ).root;
 
-      const children = root.children[0].children;
-      expect(children).to.have.lengthOf(3);
-      expect(children[0].children[0].props.value).to.equal("*.slack.com");
-      expect(children[1].children[0].props.value).to.equal(
-        "www.google.com/maps"
-      );
-      expect(children[2].props.name).to.equal("add");
+      const rows = root.findAllByProps({
+        className: "form-blacklist-form-row",
+      });
+      expect(rows).to.have.lengthOf(2);
+      expect(
+        rows[0].findByProps({ className: "column-url" }).props.value
+      ).to.equal("*.slack.com");
+      expect(
+        rows[1].findByProps({ className: "column-url" }).props.value
+      ).to.equal("www.google.com/maps");
+
+      expect(() => root.findByType(AddButton)).not.throw();
     });
 
     it("renders blank value", () => {
       const root = ReactTestRenderer.create(<BlacklistForm />).root;
 
-      const children = root.children[0].children;
-      expect(children).to.have.lengthOf(1);
-      expect(children[0].props.name).to.equal("add");
+      const rows = root.findAllByProps({
+        className: "form-blacklist-form-row",
+      });
+      expect(rows).to.be.empty;
     });
   });
 
   describe("onChange", () => {
-    let container;
+    let container: HTMLDivElement;
 
     beforeEach(() => {
       container = document.createElement("div");
@@ -44,7 +51,6 @@ describe("settings/form/BlacklistForm", () => {
 
     afterEach(() => {
       document.body.removeChild(container);
-      container = null;
     });
 
     it("invokes onChange event on edit", (done) => {
@@ -65,7 +71,9 @@ describe("settings/form/BlacklistForm", () => {
         );
       });
 
-      const input = document.querySelectorAll("input[type=text]")[0];
+      const input = document.querySelectorAll(
+        "input[type=text]"
+      )[0] as HTMLInputElement;
       input.value = "gitter.im";
       ReactTestUtils.Simulate.change(input);
     });
@@ -104,7 +112,9 @@ describe("settings/form/BlacklistForm", () => {
         );
       });
 
-      const button = document.querySelector("input[type=button].ui-add-button");
+      const button = document.querySelector(
+        "input[type=button].ui-add-button"
+      ) as HTMLButtonElement;
       ReactTestUtils.Simulate.click(button);
     });
   });
diff --git a/test/settings/components/form/KeymapsForm.test.tsx b/test/settings/components/form/KeymapsForm.test.tsx
index 0a88db5..1cec889 100644
--- a/test/settings/components/form/KeymapsForm.test.tsx
+++ b/test/settings/components/form/KeymapsForm.test.tsx
@@ -3,7 +3,7 @@ import ReactDOM from "react-dom";
 import ReactTestRenderer from "react-test-renderer";
 import ReactTestUtils from "react-dom/test-utils";
 import KeymapsForm from "../../../../src/settings/components/form/KeymapsForm";
-import { FormKeymaps } from "shared/SettingData";
+import { FormKeymaps } from "../../../../src/shared/SettingData";
 import { expect } from "chai";
 
 describe("settings/form/KeymapsForm", () => {
@@ -37,7 +37,7 @@ describe("settings/form/KeymapsForm", () => {
   });
 
   describe("onChange event", () => {
-    let container;
+    let container: HTMLDivElement;
 
     beforeEach(() => {
       container = document.createElement("div");
@@ -46,7 +46,6 @@ describe("settings/form/KeymapsForm", () => {
 
     afterEach(() => {
       document.body.removeChild(container);
-      container = null;
     });
 
     it("invokes onChange event on edit", (done) => {
@@ -68,7 +67,9 @@ describe("settings/form/KeymapsForm", () => {
         );
       });
 
-      const input = document.getElementById('scroll.vertically?{"count":1}');
+      const input = document.getElementById(
+        'scroll.vertically?{"count":1}'
+      ) as HTMLInputElement;
       input.value = "jjj";
       ReactTestUtils.Simulate.change(input);
     });
diff --git a/test/settings/components/form/PropertiesForm.test.tsx b/test/settings/components/form/PropertiesForm.test.tsx
index 4dc00a2..acf02b8 100644
--- a/test/settings/components/form/PropertiesForm.test.tsx
+++ b/test/settings/components/form/PropertiesForm.test.tsx
@@ -2,7 +2,8 @@ import React from "react";
 import ReactDOM from "react-dom";
 import ReactTestRenderer from "react-test-renderer";
 import ReactTestUtils from "react-dom/test-utils";
-import PropertiesForm from "settings/components/form/PropertiesForm";
+import PropertiesForm from "../../../../src/settings/components/form/PropertiesForm";
+import { expect } from "chai";
 
 describe("settings/form/PropertiesForm", () => {
   describe("render", () => {
@@ -38,7 +39,7 @@ describe("settings/form/PropertiesForm", () => {
   });
 
   describe("onChange", () => {
-    let container;
+    let container: HTMLDivElement;
 
     beforeEach(() => {
       container = document.createElement("div");
@@ -47,7 +48,6 @@ describe("settings/form/PropertiesForm", () => {
 
     afterEach(() => {
       document.body.removeChild(container);
-      container = null;
     });
 
     it("invokes onChange event on text changed", (done) => {
@@ -65,7 +65,9 @@ describe("settings/form/PropertiesForm", () => {
         );
       });
 
-      const input = document.querySelector("input[name=myvalue]");
+      const input = document.querySelector(
+        "input[name=myvalue]"
+      ) as HTMLInputElement;
       input.value = "abcd";
       ReactTestUtils.Simulate.change(input);
     });
@@ -85,7 +87,9 @@ describe("settings/form/PropertiesForm", () => {
         );
       });
 
-      const input = document.querySelector("input[name=myvalue]");
+      const input = document.querySelector(
+        "input[name=myvalue]"
+      ) as HTMLInputElement;
       input.value = "1234";
       ReactTestUtils.Simulate.change(input);
     });
@@ -105,7 +109,9 @@ describe("settings/form/PropertiesForm", () => {
         );
       });
 
-      const input = document.querySelector("input[name=myvalue]");
+      const input = document.querySelector(
+        "input[name=myvalue]"
+      ) as HTMLInputElement;
       input.checked = true;
       ReactTestUtils.Simulate.change(input);
     });
diff --git a/test/settings/components/form/SearchEngineForm.test.tsx b/test/settings/components/form/SearchEngineForm.test.tsx
index ccbd197..5f835cc 100644
--- a/test/settings/components/form/SearchEngineForm.test.tsx
+++ b/test/settings/components/form/SearchEngineForm.test.tsx
@@ -2,8 +2,9 @@ import React from "react";
 import ReactDOM from "react-dom";
 import ReactTestRenderer from "react-test-renderer";
 import ReactTestUtils from "react-dom/test-utils";
-import SearchForm from "settings/components/form/SearchForm";
-import { FormSearch } from "shared/SettingData";
+import SearchForm from "../../../../src/settings/components/form/SearchForm";
+import { FormSearch } from "../../../../src/shared/SettingData";
+import { expect } from "chai";
 
 describe("settings/form/SearchForm", () => {
   describe("render", () => {
@@ -33,7 +34,7 @@ describe("settings/form/SearchForm", () => {
   });
 
   describe("onChange event", () => {
-    let container;
+    let container: HTMLDivElement;
 
     beforeEach(() => {
       container = document.createElement("div");
@@ -42,7 +43,6 @@ describe("settings/form/SearchForm", () => {
 
     afterEach(() => {
       document.body.removeChild(container);
-      container = null;
     });
 
     it("invokes onChange event on edit", (done) => {
@@ -71,10 +71,14 @@ describe("settings/form/SearchForm", () => {
         );
       });
 
-      const radio = document.querySelectorAll("input[type=radio]");
+      const radio = document.querySelector(
+        "input[type=radio]"
+      ) as HTMLInputElement;
       radio.checked = true;
 
-      const name = document.querySelector("input[name=name]");
+      const name = document.querySelector(
+        "input[name=name]"
+      ) as HTMLInputElement;
       name.value = "louvre";
 
       ReactTestUtils.Simulate.change(name);
@@ -105,7 +109,9 @@ describe("settings/form/SearchForm", () => {
         );
       });
 
-      const button = document.querySelector("input[type=button]");
+      const button = document.querySelector(
+        "input[type=button]"
+      ) as HTMLInputElement;
       ReactTestUtils.Simulate.click(button);
     });
 
@@ -132,7 +138,9 @@ describe("settings/form/SearchForm", () => {
         );
       });
 
-      const button = document.querySelector("input[type=button].ui-add-button");
+      const button = document.querySelector(
+        "input[type=button].ui-add-button"
+      ) as HTMLInputElement;
       ReactTestUtils.Simulate.click(button);
     });
   });
diff --git a/test/settings/components/ui/input.test.tsx b/test/settings/components/ui/input.test.tsx
index 2f2b075..191bfed 100644
--- a/test/settings/components/ui/input.test.tsx
+++ b/test/settings/components/ui/input.test.tsx
@@ -1,10 +1,11 @@
 import React from "react";
 import ReactDOM from "react-dom";
 import ReactTestUtils from "react-dom/test-utils";
-import Input from "settings/components/ui/Input";
+import Input from "../../../../src/settings/components/ui/Input";
+import { expect } from "chai";
 
 describe("settings/ui/Input", () => {
-  let container;
+  let container: HTMLDivElement;
 
   beforeEach(() => {
     container = document.createElement("div");
@@ -13,7 +14,6 @@ describe("settings/ui/Input", () => {
 
   afterEach(() => {
     document.body.removeChild(container);
-    container = null;
   });
 
   context("type=text", () => {
@@ -25,8 +25,8 @@ describe("settings/ui/Input", () => {
         );
       });
 
-      const label = document.querySelector("label");
-      const input = document.querySelector("input");
+      const label = document.querySelector("label")!!;
+      const input = document.querySelector("input")!!;
       expect(label.textContent).to.contain("myfield");
       expect(input.type).to.contain("text");
       expect(input.name).to.contain("myname");
@@ -42,7 +42,7 @@ describe("settings/ui/Input", () => {
             label="myfield"
             value="myvalue"
             onChange={(e) => {
-              expect(e.target.value).to.equal("newvalue");
+              expect((e.target as HTMLInputElement).value).to.equal("newvalue");
               done();
             }}
           />,
@@ -50,7 +50,7 @@ describe("settings/ui/Input", () => {
         );
       });
 
-      const input = document.querySelector("input");
+      const input = document.querySelector("input")!!;
       input.value = "newvalue";
       ReactTestUtils.Simulate.change(input);
     });
@@ -65,8 +65,8 @@ describe("settings/ui/Input", () => {
         );
       });
 
-      const label = document.querySelector("label");
-      const input = document.querySelector("input");
+      const label = document.querySelector("label")!!;
+      const input = document.querySelector("input")!!;
       expect(label.textContent).to.contain("myfield");
       expect(input.type).to.contain("radio");
       expect(input.name).to.contain("myname");
@@ -82,7 +82,7 @@ describe("settings/ui/Input", () => {
             label="myfield"
             value="myvalue"
             onChange={(e) => {
-              expect(e.target.checked).to.be.true;
+              expect((e.target as HTMLInputElement).checked).to.be.true;
               done();
             }}
           />,
@@ -90,7 +90,7 @@ describe("settings/ui/Input", () => {
         );
       });
 
-      const input = document.querySelector("input");
+      const input = document.querySelector("input") as HTMLInputElement;
       input.checked = true;
       ReactTestUtils.Simulate.change(input);
     });
@@ -111,9 +111,9 @@ describe("settings/ui/Input", () => {
         );
       });
 
-      const label = document.querySelector("label");
-      const textarea = document.querySelector("textarea");
-      const error = document.querySelector(".settings-ui-input-error");
+      const label = document.querySelector("label")!!;
+      const textarea = document.querySelector("textarea")!!;
+      const error = document.querySelector(".settings-ui-input-error")!!;
       expect(label.textContent).to.contain("myfield");
       expect(textarea.nodeName).to.contain("TEXTAREA");
       expect(textarea.name).to.contain("myname");
@@ -130,7 +130,7 @@ describe("settings/ui/Input", () => {
             label="myfield"
             value="myvalue"
             onChange={(e) => {
-              expect(e.target.value).to.equal("newvalue");
+              expect((e.target as HTMLInputElement).value).to.equal("newvalue");
               done();
             }}
           />,
@@ -138,7 +138,7 @@ describe("settings/ui/Input", () => {
         );
       });
 
-      const input = document.querySelector("textarea");
+      const input = document.querySelector("textarea")!!;
       input.value = "newvalue";
       ReactTestUtils.Simulate.change(input);
     });
diff --git a/test/settings/reducers/setting.test.ts b/test/settings/reducers/setting.test.ts
index bb5cfa5..99c4c80 100644
--- a/test/settings/reducers/setting.test.ts
+++ b/test/settings/reducers/setting.test.ts
@@ -1,54 +1,61 @@
-import * as actions from "settings/actions";
-import settingReducer from "settings/reducers/setting";
+import * as actions from "../../../src/settings/actions";
+import settingReducer from "../../../src/settings/reducers/setting";
+import { expect } from "chai";
+import {
+  FormSettings,
+  JSONTextSettings,
+  SettingSource,
+} from "../../../src/shared/SettingData";
+import { DefaultSetting } from "../../../src/shared/settings/Settings";
 
 describe("settings setting reducer", () => {
   it("return the initial state", () => {
-    const state = settingReducer(undefined, {});
+    const state = settingReducer(undefined, {} as any);
     expect(state).to.have.deep.property("source", "json");
     expect(state).to.have.deep.property("error", "");
   });
 
   it("return next state for SETTING_SET_SETTINGS", () => {
-    const action = {
+    const action: actions.SettingAction = {
       type: actions.SETTING_SET_SETTINGS,
-      source: "json",
-      json: '{ "key": "value" }',
-      form: {},
+      source: SettingSource.JSON,
+      json: JSONTextSettings.fromText('{ "key": "value" }'),
+      form: FormSettings.fromSettings(DefaultSetting),
     };
     const state = settingReducer(undefined, action);
-    expect(state).to.have.deep.property("source", "json");
-    expect(state).to.have.deep.property("json", '{ "key": "value" }');
-    expect(state).to.have.deep.property("form", {});
+    expect(state.source).to.equal("json");
+    expect(state.json!!.toJSONText()).to.equal('{ "key": "value" }');
+    expect(state.form).to.deep.equal(action.form);
   });
 
   it("return next state for SETTING_SHOW_ERROR", () => {
-    const action = {
+    const action: actions.SettingAction = {
       type: actions.SETTING_SHOW_ERROR,
       error: "bad value",
-      json: "{}",
+      json: JSONTextSettings.fromText("{}"),
     };
     const state = settingReducer(undefined, action);
-    expect(state).to.have.deep.property("error", "bad value");
-    expect(state).to.have.deep.property("json", "{}");
+    expect(state.error).to.equal("bad value");
+    expect(state.json!!.toJSONText()).to.equal("{}");
   });
 
   it("return next state for SETTING_SWITCH_TO_FORM", () => {
-    const action = {
+    const action: actions.SettingAction = {
       type: actions.SETTING_SWITCH_TO_FORM,
-      form: {},
+      form: FormSettings.fromSettings(DefaultSetting),
     };
     const state = settingReducer(undefined, action);
-    expect(state).to.have.deep.property("form", {});
-    expect(state).to.have.deep.property("source", "form");
+    expect(state.form).to.deep.equal(action.form);
+    expect(state.source).to.equal("form");
   });
 
   it("return next state for SETTING_SWITCH_TO_JSON", () => {
-    const action = {
+    const action: actions.SettingAction = {
       type: actions.SETTING_SWITCH_TO_JSON,
-      json: "{}",
+      json: JSONTextSettings.fromText("{}"),
     };
     const state = settingReducer(undefined, action);
-    expect(state).to.have.deep.property("json", "{}");
-    expect(state).to.have.deep.property("source", "json");
+    expect(state.json!!.toJSONText()).to.equal("{}");
+    expect(state.source).to.equal(SettingSource.JSON);
   });
 });
diff --git a/test/shared/operations.test.ts b/test/shared/operations.test.ts
index 94986ac..449b25e 100644
--- a/test/shared/operations.test.ts
+++ b/test/shared/operations.test.ts
@@ -1,12 +1,13 @@
-import * as operations from "shared/operations";
+import * as operations from "../../src/shared/operations";
+import { expect } from "chai";
 
 describe("operations", () => {
   describe("#valueOf", () => {
     it("returns an Operation", () => {
-      const op: operations.Operation = operations.valueOf({
+      const op = operations.valueOf({
         type: operations.SCROLL_VERTICALLY,
         count: 10,
-      });
+      }) as operations.ScrollVerticallyOperation;
       expect(op.type).to.equal(operations.SCROLL_VERTICALLY);
       expect(op.count).to.equal(10);
     });
@@ -20,9 +21,9 @@ describe("operations", () => {
     });
 
     it("fills default valus of optional parameter", () => {
-      const op: operations.Operation = operations.valueOf({
+      const op = operations.valueOf({
         type: operations.COMMAND_SHOW_OPEN,
-      });
+      }) as operations.CommandShowOpenOperation;
 
       expect(op.type).to.equal(operations.COMMAND_SHOW_OPEN);
       expect(op.alter).to.be.false;
@@ -37,7 +38,7 @@ describe("operations", () => {
       ).to.throw(TypeError);
 
       expect(() =>
-        valueOf({
+        operations.valueOf({
           type: operations.COMMAND_SHOW_OPEN,
           alter: "true",
         })
-- 
cgit v1.2.3

