From 04e526481179cbd64de1d2f4803ebdd719155f8c Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 13 Aug 2020 21:21:07 +0900 Subject: Define color theme --- src/console/components/Theme.ts | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/console/components/Theme.ts (limited to 'src') diff --git a/src/console/components/Theme.ts b/src/console/components/Theme.ts new file mode 100644 index 0000000..dd7baa5 --- /dev/null +++ b/src/console/components/Theme.ts @@ -0,0 +1,53 @@ +import baseStyled, { ThemedStyledInterface } from "styled-components"; + +type Theme = { + completionTitleBackground: string; + completionTitleForeground: string; + completionItemBackground: string; + completionItemForeground: string; + completionItemDescriptionForeground: string; + completionSelectedBackground: string; + completionSelectedForeground: string; + commandBackground: string; + commandForeground: string; + consoleErrorBackground: string; + consoleErrorForeground: string; + consoleInfoBackground: string; + consoleInfoForeground: string; +}; + +export const LightTheme: Theme = { + completionTitleBackground: "lightgray", + completionTitleForeground: "#000000", + completionItemBackground: "#ffffff", + completionItemForeground: "#000000", + completionItemDescriptionForeground: "#008000", + completionSelectedBackground: "#ffff00", + completionSelectedForeground: "#000000", + commandBackground: "#ffffff", + commandForeground: "#000000", + consoleErrorBackground: "#ff0000", + consoleErrorForeground: "#ffffff", + consoleInfoBackground: "#ffffff", + consoleInfoForeground: "#018786", +}; + +export const DarkTheme: Theme = { + completionTitleBackground: "#052027", + completionTitleForeground: "white", + completionItemBackground: "#2f474f", + completionItemForeground: "white", + completionItemDescriptionForeground: "#86fab0", + completionSelectedBackground: "#eeff41", + completionSelectedForeground: "#000000", + commandBackground: "#052027", + commandForeground: "white", + consoleErrorBackground: "red", + consoleErrorForeground: "white", + consoleInfoBackground: "#052027", + consoleInfoForeground: "#ffffff", +}; + +const styled = baseStyled as ThemedStyledInterface; + +export default styled; -- cgit v1.2.3 From 5fd1ff9fda83c852349430f472387ef5d73d3700 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 13 Aug 2020 21:41:22 +0900 Subject: Migrate Vanilla CSS to styled-components --- src/console/components/Console.tsx | 47 ++++++---- src/console/components/console.scss | 103 +++------------------ src/console/components/console/CompletionItem.tsx | 63 ++++++++----- src/console/components/console/CompletionTitle.tsx | 13 ++- src/console/components/console/Input.tsx | 26 +++++- src/console/components/console/Message.tsx | 31 ++++--- 6 files changed, 133 insertions(+), 150 deletions(-) (limited to 'src') diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx index a0e22e4..a23c459 100644 --- a/src/console/components/Console.tsx +++ b/src/console/components/Console.tsx @@ -11,6 +11,13 @@ import CommandLineParser, { } from "../commandline/CommandLineParser"; import { Command } from "../../shared/Command"; import ColorScheme from "../../shared/ColorScheme"; +import { LightTheme, DarkTheme } from "./Theme"; +import styled from "./Theme"; +import { ThemeProvider } from "styled-components"; + +const ConsoleWrapper = styled.div` + border-top: 1px solid gray; +`; const COMPLETION_MAX_ITEMS = 33; @@ -143,28 +150,34 @@ class Console extends React.Component { case "command": case "find": return ( -
- - -
+ + + + + + ); case "info": case "error": return ( -
+ {this.props.messageText} -
+ ); default: return null; diff --git a/src/console/components/console.scss b/src/console/components/console.scss index ccb769b..c9ffae7 100644 --- a/src/console/components/console.scss +++ b/src/console/components/console.scss @@ -33,6 +33,18 @@ html, body, * { margin: 0; padding: 0; + + font-style: normal; + font-family: monospace; + font-size: 12px; + line-height: 16px; +} + +input { + font-style: normal; + font-family: monospace; + font-size: 12px; + line-height: 16px; } body { @@ -47,95 +59,4 @@ body { bottom: 0; margin: 0; padding: 0; - - @mixin console-font { - font-style: normal; - font-family: monospace; - font-size: 12px; - line-height: 16px; - } - - &-command-wrapper { - border-top: 1px solid gray; - } - - &-completion { - @include console-font; - - &-title { - background-color: var(--completion-title-background); - color: var(--completion-title-foreground); - font-weight: bold; - margin: 0; - padding: 0; - } - - &-item { - background-color: var(--completion-item-background); - color: var(--completion-item-foreground); - - padding-left: 1.5rem; - background-position: 0 center; - background-size: contain; - background-repeat: no-repeat; - white-space: pre; - - &.vimvixen-completion-selected { - background-color: var(--completion-selected-background); - color: var(--completion-selected-foreground); - } - - &-caption { - display: inline-block; - width: 40%; - text-overflow: ellipsis; - overflow: hidden; - } - - &-url { - display: inline-block; - color: var(--completion-item-description-foreground); - width: 60%; - text-overflow: ellipsis; - overflow: hidden; - } - } - } - - &-message { - @include console-font; - - border-top: 1px solid gray; - } - - &-error { - background-color: var(--console-error-background); - color: var(--console-error-foreground); - font-weight: bold; - } - - &-info { - background-color: var(--console-info-background); - color: var(--console-info-foreground); - font-weight: normal; - } - - &-command { - background-color: var(--command-background); - color: var(--command-foreground); - display: flex; - - &-prompt { - @include console-font; - } - - &-input { - border: none; - flex-grow: 1; - background-color: var(--command-background); - color: var(--command-foreground); - - @include console-font; - } - } } diff --git a/src/console/components/console/CompletionItem.tsx b/src/console/components/console/CompletionItem.tsx index 657f360..da07bf0 100644 --- a/src/console/components/console/CompletionItem.tsx +++ b/src/console/components/console/CompletionItem.tsx @@ -1,5 +1,37 @@ import React from "react"; -import PropTypes from "prop-types"; +import styled from "../Theme"; + +const Container = styled.li<{ icon: string; highlight: boolean }>` + backgroundimage: ${({ icon }) => "url(" + icon + ")"}; + background-color: ${({ highlight, theme }) => + highlight + ? theme.completionSelectedBackground + : theme.completionItemBackground}; + color: ${({ highlight, theme }) => + highlight + ? theme.completionSelectedForeground + : theme.completionItemForeground}; + padding-left: 1.5rem; + background-position: 0 center; + background-size: contain; + background-repeat: no-repeat; + white-space: pre; +`; + +const Caption = styled.span` + display: inline-block; + width: 40%; + text-overflow: ellipsis; + overflow: hidden; +`; + +const Description = styled.span` + display: inline-block; + color: ${({ theme }) => theme.completionItemDescriptionForeground}; + width: 60%; + text-overflow: ellipsis; + overflow: hidden; +`; interface Props { highlight: boolean; @@ -8,28 +40,11 @@ interface Props { icon?: string; } -const CompletionItem = (props: Props) => { - let className = "vimvixen-console-completion-item"; - if (props.highlight) { - className += " vimvixen-completion-selected"; - } - return ( -
  • - - {props.caption} - - {props.url} -
  • - ); -}; - -CompletionItem.propTypes = { - highlight: PropTypes.bool, - caption: PropTypes.string, - url: PropTypes.string, -}; +const CompletionItem: React.FC = ({ highlight, caption, url, icon }) => ( + + {caption} + {url} + +); export default CompletionItem; diff --git a/src/console/components/console/CompletionTitle.tsx b/src/console/components/console/CompletionTitle.tsx index 7257006..55c3c2e 100644 --- a/src/console/components/console/CompletionTitle.tsx +++ b/src/console/components/console/CompletionTitle.tsx @@ -1,11 +1,20 @@ import React from "react"; +import styled from "../Theme"; + +const Li = styled.li` + background-color: ${({ theme }) => theme.completionTitleBackground}; + color: ${({ theme }) => theme.completionTitleForeground}; + font-weight: bold; + margin: 0; + padding: 0; +`; interface Props { title: string; } -const CompletionTitle = (props: Props) => { - return
  • {props.title}
  • ; +const CompletionTitle: React.FC = ({ title }) => { + return
  • {title}
  • ; }; export default CompletionTitle; diff --git a/src/console/components/console/Input.tsx b/src/console/components/console/Input.tsx index e412a0c..61fbc46 100644 --- a/src/console/components/console/Input.tsx +++ b/src/console/components/console/Input.tsx @@ -1,4 +1,22 @@ import React from "react"; +import styled from "../Theme"; + +const Container = styled.div` + background-color: ${({ theme }) => theme.commandBackground}; + color: ${({ theme }) => theme.commandForeground}; + display: flex; +`; + +const Prompt = styled.i` + font-style: normal; +`; + +const InputInner = styled.input` + border: none; + flex-grow: 1; + background-color: ${({ theme }) => theme.commandBackground}; + color: ${({ theme }) => theme.commandForeground}; +`; interface Props { mode: string; @@ -32,9 +50,9 @@ class Input extends React.Component { } return ( -
    - {prompt} - + {prompt} + { onChange={this.props.onChange} value={this.props.value} /> -
    + ); } } diff --git a/src/console/components/console/Message.tsx b/src/console/components/console/Message.tsx index fd1c9d7..e039020 100644 --- a/src/console/components/console/Message.tsx +++ b/src/console/components/console/Message.tsx @@ -1,24 +1,31 @@ import React from "react"; +import styled from "../Theme"; + +const Error = styled.p` + border-top: 1px solid gray; + background-color: ${({ theme }) => theme.consoleErrorBackground}; + color: ${({ theme }) => theme.consoleErrorForeground}; + font-weight: bold; +`; + +const Info = styled.p` + border-top: 1px solid gray; + background-color: ${({ theme }) => theme.consoleInfoBackground}; + color: ${({ theme }) => theme.consoleInfoForeground}; + font-weight: normal; +`; interface Props { mode: string; children: string; } -const Message = (props: Props) => { - switch (props.mode) { +const Message: React.FC = ({ mode, children }) => { + switch (mode) { case "error": - return ( -

    - {props.children} -

    - ); + return {children}; case "info": - return ( -

    - {props.children} -

    - ); + return {children}; } return null; }; -- cgit v1.2.3 From a70122acd6595ba26f084d22185c40f6da65b5ac Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 16 Aug 2020 15:38:54 +0900 Subject: Remove unused styles --- src/console/components/console.scss | 32 --------------------------- src/console/components/console/Completion.tsx | 2 +- 2 files changed, 1 insertion(+), 33 deletions(-) (limited to 'src') diff --git a/src/console/components/console.scss b/src/console/components/console.scss index c9ffae7..2d548df 100644 --- a/src/console/components/console.scss +++ b/src/console/components/console.scss @@ -1,35 +1,3 @@ -[data-theme="light"] { - --completion-title-background: lightgray; - --completion-title-foreground: #000000; - --completion-item-background: #ffffff; - --completion-item-foreground: #000000; - --completion-item-description-foreground: #008000; - --completion-selected-background: #ffff00; - --completion-selected-foreground: #000000; - --command-background: #ffffff; - --command-foreground: #000000; - --console-error-background: #ff0000; - --console-error-foreground: #ffffff; - --console-info-background: #ffffff; - --console-info-foreground: #018786; -} - -[data-theme="dark"] { - --completion-title-background: #052027; - --completion-title-foreground: white; - --completion-item-background: #2f474f; - --completion-item-foreground: white; - --completion-item-description-foreground: #86fab0; - --completion-selected-background: #eeff41; - --completion-selected-foreground: #000000; - --command-background: #052027; - --command-foreground: white; - --console-error-background: red; - --console-error-foreground: white; - --console-info-background: #052027; - --console-info-foreground: #ffffff; -} - html, body, * { margin: 0; padding: 0; diff --git a/src/console/components/console/Completion.tsx b/src/console/components/console/Completion.tsx index 9b4cf15..aefee32 100644 --- a/src/console/components/console/Completion.tsx +++ b/src/console/components/console/Completion.tsx @@ -85,7 +85,7 @@ class Completion extends React.Component { const viewOffset = this.state.viewOffset; eles = eles.slice(viewOffset, viewOffset + this.props.size); - return
      {eles}
    ; + return
      {eles}
    ; } } -- cgit v1.2.3 From 264d69c933370b3321dfcd83d823222e730e3fe0 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 16 Aug 2020 16:39:57 +0900 Subject: Improve a11y in completion items --- src/console/components/console/Completion.tsx | 48 ++++++++++++++++------ src/console/components/console/CompletionItem.tsx | 18 +++++--- src/console/components/console/CompletionTitle.tsx | 10 +++-- 3 files changed, 54 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/console/components/console/Completion.tsx b/src/console/components/console/Completion.tsx index aefee32..56c5de3 100644 --- a/src/console/components/console/Completion.tsx +++ b/src/console/components/console/Completion.tsx @@ -63,29 +63,51 @@ class Completion extends React.Component { } render() { - let eles = []; - let index = 0; + let itemIndex = 0; + let viewIndex = 0; + const groups: Array = []; + const viewOffset = this.state.viewOffset; + const viewSize = this.props.size; - for (const group of this.props.completions) { - eles.push(); + this.props.completions.forEach((group, groupIndex) => { + const items = []; + const title = ( + + ); + ++viewIndex; for (const item of group.items) { - eles.push( + items.push( ); - ++index; + ++viewIndex; + ++itemIndex; } - } - - const viewOffset = this.state.viewOffset; - eles = eles.slice(viewOffset, viewOffset + this.props.size); + groups.push( +
    + {title} +
      {items}
    +
    + ); + }); - return
      {eles}
    ; + return
    {groups}
    ; } } diff --git a/src/console/components/console/CompletionItem.tsx b/src/console/components/console/CompletionItem.tsx index da07bf0..76db5b5 100644 --- a/src/console/components/console/CompletionItem.tsx +++ b/src/console/components/console/CompletionItem.tsx @@ -1,7 +1,11 @@ import React from "react"; import styled from "../Theme"; -const Container = styled.li<{ icon: string; highlight: boolean }>` +const Container = styled.li<{ + shown: boolean; + icon: string; + highlight: boolean; +}>` backgroundimage: ${({ icon }) => "url(" + icon + ")"}; background-color: ${({ highlight, theme }) => highlight @@ -11,6 +15,7 @@ const Container = styled.li<{ icon: string; highlight: boolean }>` highlight ? theme.completionSelectedForeground : theme.completionItemForeground}; + display: ${({ shown }) => (shown ? "display" : "none")}; padding-left: 1.5rem; background-position: 0 center; background-size: contain; @@ -34,16 +39,19 @@ const Description = styled.span` `; interface Props { + shown: boolean; highlight: boolean; caption?: string; url?: string; icon?: string; } -const CompletionItem: React.FC = ({ highlight, caption, url, icon }) => ( - - {caption} - {url} +const CompletionItem: React.FC & Props> = ( + props +) => ( + + {props.caption} + {props.url} ); diff --git a/src/console/components/console/CompletionTitle.tsx b/src/console/components/console/CompletionTitle.tsx index 55c3c2e..ec2fc8b 100644 --- a/src/console/components/console/CompletionTitle.tsx +++ b/src/console/components/console/CompletionTitle.tsx @@ -1,7 +1,8 @@ import React from "react"; import styled from "../Theme"; -const Li = styled.li` +const Li = styled.li<{ shown: boolean }>` + display: ${({ shown }) => (shown ? "display" : "none")}; background-color: ${({ theme }) => theme.completionTitleBackground}; color: ${({ theme }) => theme.completionTitleForeground}; font-weight: bold; @@ -10,11 +11,12 @@ const Li = styled.li` `; interface Props { + shown: boolean; title: string; } -const CompletionTitle: React.FC = ({ title }) => { - return
  • {title}
  • ; -}; +const CompletionTitle: React.FC & Props> = ( + props +) =>
  • {props.title}
  • ; export default CompletionTitle; -- cgit v1.2.3 From d53f010cc92f1fcb9580ca770766790e783e28a5 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 16 Aug 2020 17:57:54 +0900 Subject: Fix Completion.test --- e2e/lib/Console.ts | 39 ++-- src/console/components/console/Completion.tsx | 1 + .../console/components/console/Completion.test.tsx | 259 +++++++++++++++------ .../components/console/CompletionItem.test.tsx | 21 ++ .../components/console/CompletionTitle.test.tsx | 15 ++ 5 files changed, 243 insertions(+), 92 deletions(-) create mode 100644 test/console/components/console/CompletionItem.test.tsx create mode 100644 test/console/components/console/CompletionTitle.test.tsx (limited to 'src') diff --git a/e2e/lib/Console.ts b/e2e/lib/Console.ts index 2c128d1..2d397c6 100644 --- a/e2e/lib/Console.ts +++ b/e2e/lib/Console.ts @@ -1,7 +1,11 @@ import { WebDriver, By, Key } from "selenium-webdriver"; +export type CompletionGroups = { + name: string; + items: Array; +}; + export type CompletionItem = { - type: string; text: string; highlight: boolean; }; @@ -25,9 +29,7 @@ export class Console { } async execCommand(command: string): Promise { - const input = await this.webdriver.findElement( - By.css("input.vimvixen-console-command-input") - ); + const input = await this.webdriver.findElement(By.css("input")); await input.sendKeys(command, Key.ENTER); } @@ -52,27 +54,20 @@ export class Console { getCompletions(): Promise { return this.webdriver.executeScript(() => { - const items = document.querySelectorAll( - ".vimvixen-console-completion > li" - ); - if (items.length === 0) { + const groups = document.querySelectorAll("[role=group]"); + if (groups.length === 0) { throw new Error("completion items not found"); } - const objs = []; - for (const li of Array.from(items)) { - if (li.classList.contains("vimvixen-console-completion-title")) { - objs.push({ type: "title", text: li.textContent!.trim() }); - } else if (li.classList.contains("vimvixen-console-completion-item")) { - const highlight = li.classList.contains( - "vimvixen-completion-selected" - ); - objs.push({ type: "item", text: li.textContent!.trim(), highlight }); - } else { - throw new Error(`unexpected class: ${li.className}`); - } - } - return objs; + return Array.from(groups).map((group) => ({ + name: group.textContent!.trim(), + items: Array.from(group.querySelectorAll("[role=menuitem]")).map( + (item) => ({ + text: item.textContent!.trim(), + highlight: item.getAttribute("aria-selected") === "true", + }) + ), + })); }); } diff --git a/src/console/components/console/Completion.tsx b/src/console/components/console/Completion.tsx index 56c5de3..09ae278 100644 --- a/src/console/components/console/Completion.tsx +++ b/src/console/components/console/Completion.tsx @@ -89,6 +89,7 @@ class Completion extends React.Component { caption={item.caption} url={item.url} highlight={itemIndex === this.props.select} + aria-selected={itemIndex === this.props.select} role="menuitem" /> ); diff --git a/test/console/components/console/Completion.test.tsx b/test/console/components/console/Completion.test.tsx index 921720b..0e4e21f 100644 --- a/test/console/components/console/Completion.test.tsx +++ b/test/console/components/console/Completion.test.tsx @@ -1,11 +1,11 @@ import React from "react"; import Completion from "../../../../src/console/components/console/Completion"; -import ReactTestRenderer, { ReactTestInstance } from "react-test-renderer"; +import ReactTestRenderer 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", () => { +describe("console/components/console/completion/Completion", () => { const completions = [ { name: "Fruit", @@ -30,27 +30,19 @@ describe("console/components/console/completion", () => { ).root; - // const children = root.findByType('ul').children as Array; - const children = root.findByType("ul").children as Array; - 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"); - expect(children[3].props.caption).to.equal("cherry"); - expect(children[4].props.title).to.equal("Element"); - expect(children[5].props.caption).to.equal("argon"); - expect(children[6].props.caption).to.equal("boron"); - expect(children[7].props.caption).to.equal("carbon"); + const groups = root.findAllByProps({ role: "group" }); + expect(groups).to.have.lengthOf(2); + + groups.forEach((group, i) => { + const title = group.findByType(CompletionTitle); + expect(title.props.title).to.equal(completions[i].name); + + const items = group.findAllByType(CompletionItem); + expect(items).to.have.lengthOf(completions[i].items.length); + items.forEach((item, j) => { + expect(item.props.caption).to.equal(completions[i].items[j].caption); + }); + }); }); it("highlight current item", () => { @@ -58,8 +50,8 @@ describe("console/components/console/completion", () => { ).root; - const children = root.findByType("ul").children as Array; - expect(children[5].props.highlight).to.be.true; + const items = root.findAllByType(CompletionItem); + expect(items[3].props.highlight).to.be.true; }); it("does not highlight any items", () => { @@ -67,8 +59,8 @@ describe("console/components/console/completion", () => { ).root; - const children = root.findByType("ul").findAllByType(CompletionItem); - expect(children.every((e) => e.props.highlight === false)).to.be.true; + const items = root.findAllByType(CompletionItem); + expect(items.every((item) => item.props.highlight === false)).to.be.true; }); it("limits completion items", () => { @@ -76,19 +68,35 @@ describe("console/components/console/completion", () => { ).root; - let children = root.findByType("ul").children as Array; - expect(children).to.have.lengthOf(3); + const showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); - expect(children[0].props.title).to.equal("Fruit"); - expect(children[1].props.caption).to.equal("apple"); - expect(children[2].props.caption).to.equal("banana"); + expect(showns).to.deep.equal([ + true, + true, + true, + false, + false, + false, + false, + false, + ]); root = ReactTestRenderer.create( ).root; - children = root.findByType("ul").children as Array; - expect(children[1].props.highlight).to.be.true; + const items = root + .findAllByType(CompletionItem) + .map((item) => item.props.shown); + expect(items[1]).to.be.true; }); it("scrolls up to down with select", () => { @@ -97,33 +105,76 @@ describe("console/components/console/completion", () => { ); const root = component.root; - let children = root.findByType("ul").children as Array; - expect(children).to.have.lengthOf(3); - expect(children[0].props.title).to.equal("Fruit"); - expect(children[1].props.caption).to.equal("apple"); - expect(children[2].props.caption).to.equal("banana"); + let items = root.findAllByType(CompletionItem); + let showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); + expect(showns).to.deep.equal([ + true, + true, + true, + false, + false, + false, + false, + false, + ]); component.update( ); - - children = root.findByType("ul").children as Array; - expect(children).to.have.lengthOf(3); - expect(children[0].props.caption).to.equal("apple"); - expect(children[1].props.caption).to.equal("banana"); - expect(children[2].props.caption).to.equal("cherry"); - expect(children[2].props.highlight).to.be.true; + items = root.findAllByType(CompletionItem); + showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); + expect(showns).to.deep.equal([ + false, + true, + true, + true, + false, + false, + false, + false, + ]); + expect(items[2].props.highlight).to.be.true; component.update( ); - - children = root.findByType("ul").children as Array; - expect(children).to.have.lengthOf(3); - expect(children[0].props.caption).to.equal("cherry"); - expect(children[1].props.title).to.equal("Element"); - expect(children[2].props.caption).to.equal("argon"); - expect(children[2].props.highlight).to.be.true; + items = root.findAllByType(CompletionItem); + showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); + expect(showns).to.deep.equal([ + false, + false, + false, + true, + true, + true, + false, + false, + ]); + expect(items[3].props.highlight).to.be.true; }); it("scrolls down to up with select", () => { @@ -132,34 +183,102 @@ describe("console/components/console/completion", () => { ); const root = component.root; - let children = root.findByType("ul").children as Array; - expect(children).to.have.lengthOf(3); - expect(children[0].props.caption).to.equal("argon"); - expect(children[1].props.caption).to.equal("boron"); - expect(children[2].props.caption).to.equal("carbon"); + let items = root.findAllByType(CompletionItem); + let showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); + + expect(showns).to.deep.equal([ + false, + false, + false, + false, + false, + true, + true, + true, + ]); + expect(items[5].props.highlight).to.be.true; component.update( ); - - children = root.findByType("ul").children as Array; - expect(children[1].props.highlight).to.be.true; + items = root.findAllByType(CompletionItem); + showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); + expect(showns).to.deep.equal([ + false, + false, + false, + false, + false, + true, + true, + true, + ]); + expect(items[4].props.highlight).to.be.true; component.update( ); - - children = root.findByType("ul").children as Array; - expect(children[0].props.highlight).to.be.true; + items = root.findAllByType(CompletionItem); + showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); + expect(showns).to.deep.equal([ + false, + false, + false, + false, + false, + true, + true, + true, + ]); + expect(items[3].props.highlight).to.be.true; component.update( ); - - children = root.findByType("ul").children as Array; - expect(children[0].props.caption).to.equal("cherry"); - expect(children[1].props.title).to.equal("Element"); - expect(children[2].props.caption).to.equal("argon"); - expect(children[0].props.highlight).to.be.true; + items = root.findAllByType(CompletionItem); + showns = root + .findAllByProps({ role: "group" }) + .map((group) => + [ + group.findByType(CompletionTitle).props.shown, + group.findAllByType(CompletionItem).map((item) => item.props.shown), + ].flat() + ) + .flat(); + expect(showns).to.deep.equal([ + false, + false, + false, + true, + true, + true, + false, + false, + ]); + expect(items[2].props.highlight).to.be.true; }); }); diff --git a/test/console/components/console/CompletionItem.test.tsx b/test/console/components/console/CompletionItem.test.tsx new file mode 100644 index 0000000..3a4b1f2 --- /dev/null +++ b/test/console/components/console/CompletionItem.test.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import ReactTestRenderer from "react-test-renderer"; +import { expect } from "chai"; +import CompletionItem from "../../../../src/console/components/console/CompletionItem"; + +describe("console/components/console/completion/CompletionItem", () => { + it("renders a CompletionItem", () => { + const root = ReactTestRenderer.create( + + ).root; + const spans = root.findAllByType("span"); + expect(spans).to.have.lengthOf(2); + expect(spans[0].children).to.deep.equal(["twitter"]); + expect(spans[1].children).to.deep.equal(["https://twitter.com/"]); + }); +}); diff --git a/test/console/components/console/CompletionTitle.test.tsx b/test/console/components/console/CompletionTitle.test.tsx new file mode 100644 index 0000000..d8cc411 --- /dev/null +++ b/test/console/components/console/CompletionTitle.test.tsx @@ -0,0 +1,15 @@ +import React from "react"; +import ReactTestRenderer from "react-test-renderer"; +import { expect } from "chai"; +import CompletionTitle from "../../../../src/console/components/console/CompletionTitle"; + +describe("console/components/console/completion/CompletionTitle", () => { + it("renders a CompletionTitle", () => { + const root = ReactTestRenderer.create( + + ).root; + + const li = root.findByType("li"); + expect(li.children).to.deep.equal(["Fruits"]); + }); +}); -- cgit v1.2.3 From e4a9c831381a9c90ca0d44844d103b9c83a56c8d Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 16 Aug 2020 22:21:50 +0900 Subject: Improve a11y on Message component --- src/console/components/console/Message.tsx | 4 ++-- test/console/components/console/Message.test.tsx | 27 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/console/components/console/Message.test.tsx (limited to 'src') diff --git a/src/console/components/console/Message.tsx b/src/console/components/console/Message.tsx index e039020..73498fd 100644 --- a/src/console/components/console/Message.tsx +++ b/src/console/components/console/Message.tsx @@ -23,9 +23,9 @@ interface Props { const Message: React.FC = ({ mode, children }) => { switch (mode) { case "error": - return {children}; + return {children}; case "info": - return {children}; + return {children}; } return null; }; diff --git a/test/console/components/console/Message.test.tsx b/test/console/components/console/Message.test.tsx new file mode 100644 index 0000000..f8f950a --- /dev/null +++ b/test/console/components/console/Message.test.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import ReactTestRenderer from "react-test-renderer"; +import { expect } from "chai"; +import Message from "../../../../src/console/components/console/Message"; + +describe("console/components/console/completion/Message", () => { + it("renders an information message", () => { + const root = ReactTestRenderer.create(Hello!) + .root; + + const p = root.findByType("p"); + + expect(p.props["role"]).to.equal("status"); + expect(p.children).to.deep.equal(["Hello!"]); + }); + + it("renders an error message", () => { + const root = ReactTestRenderer.create( + Hello! + ).root; + + const p = root.findByType("p"); + + expect(p.props["role"]).to.equal("alert"); + expect(p.children).to.deep.equal(["Hello!"]); + }); +}); -- cgit v1.2.3 From 8bfa19885bc84e5b75009b24050be8304d52d3b2 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 21 Sep 2020 11:15:53 +0900 Subject: Fix e2e tests --- e2e/completion.test.ts | 51 +++++------ e2e/completion_buffers.test.ts | 100 ++++++++++++---------- e2e/completion_open.test.ts | 82 ++++++------------ e2e/completion_set.test.ts | 23 ++--- e2e/lib/Console.ts | 47 ++++++---- src/console/components/console/CompletionItem.tsx | 8 +- tsconfig.json | 2 +- 7 files changed, 148 insertions(+), 165 deletions(-) (limited to 'src') diff --git a/e2e/completion.test.ts b/e2e/completion.test.ts index bc065d3..c0e7052 100644 --- a/e2e/completion.test.ts +++ b/e2e/completion.test.ts @@ -28,33 +28,24 @@ describe("general completion test", () => { page = await Page.navigateTo(webdriver, "about:blank"); }); - it("should all commands on empty line", async () => { + it("should shows all commands on empty line", async () => { const console = await page.showConsole(); - const items = await console.getCompletions(); - assert.strictEqual(items.length, 12); - assert.deepStrictEqual(items[0], { - type: "title", - text: "Console Command", - }); - assert.ok(items[1].text.startsWith("set")); - assert.ok(items[2].text.startsWith("open")); - assert.ok(items[3].text.startsWith("tabopen")); + const groups = await console.getCompletions(); + assert.strictEqual(groups.length, 1); + assert.strictEqual(groups[0].title, "Console Command"); + assert.strictEqual(groups[0].items.length, 11); }); - it("should only commands filtered by prefix", async () => { + it("should shows commands filtered by prefix", async () => { const console = await page.showConsole(); await console.inputKeys("b"); - const items = await console.getCompletions(); - assert.strictEqual(items.length, 4); - assert.deepStrictEqual(items[0], { - type: "title", - text: "Console Command", - }); - assert.ok(items[1].text.startsWith("buffer")); - assert.ok(items[2].text.startsWith("bdelete")); - assert.ok(items[3].text.startsWith("bdeletes")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.ok(items[0].text.startsWith("buffer")); + assert.ok(items[1].text.startsWith("bdelete")); + assert.ok(items[2].text.startsWith("bdeletes")); }); // > byffer @@ -65,21 +56,24 @@ describe("general completion test", () => { const console = await page.showConsole(); await console.inputKeys("b"); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 4); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.strictEqual(items.length, 3); }); await console.sendKeys(Key.TAB); await eventually(async () => { - const items = await console.getCompletions(); - assert.ok(items[1].highlight); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.ok(items[0].highlight); assert.strictEqual(await console.currentValue(), "buffer"); }); await console.sendKeys(Key.TAB, Key.TAB); await eventually(async () => { - const items = await console.getCompletions(); - assert.ok(items[3].highlight); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.ok(items[2].highlight); assert.strictEqual(await console.currentValue(), "bdeletes"); }); @@ -90,8 +84,9 @@ describe("general completion test", () => { await console.sendKeys(Key.SHIFT, Key.TAB); await eventually(async () => { - const items = await console.getCompletions(); - assert.ok(items[3].highlight); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.ok(items[2].highlight); assert.strictEqual(await console.currentValue(), "bdeletes"); }); }); diff --git a/e2e/completion_buffers.test.ts b/e2e/completion_buffers.test.ts index 57603f6..13d07ea 100644 --- a/e2e/completion_buffers.test.ts +++ b/e2e/completion_buffers.test.ts @@ -72,17 +72,19 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("buffer "); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 6); - assert.deepStrictEqual(items[0], { type: "title", text: "Buffers" }); - assert.ok(items[1].text.startsWith("1:")); - assert.ok(items[2].text.startsWith("2:")); - assert.ok(items[3].text.startsWith("3:")); - assert.ok(items[4].text.startsWith("4:")); - assert.ok(items[5].text.startsWith("5:")); - - assert.ok(items[3].text.includes("%")); - assert.ok(items[5].text.includes("#")); + const groups = await console.getCompletions(); + assert.strictEqual(groups.length, 1); + assert.strictEqual(groups[0].title, "Buffers"); + + const items = groups[0].items; + assert.ok(items[0].text.startsWith("1:")); + assert.ok(items[1].text.startsWith("2:")); + assert.ok(items[2].text.startsWith("3:")); + assert.ok(items[3].text.startsWith("4:")); + assert.ok(items[4].text.startsWith("5:")); + + assert.ok(items[2].text.includes("%")); + assert.ok(items[4].text.includes("#")); }); }); @@ -91,11 +93,10 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("buffer title_site2"); await eventually(async () => { - const items = await console.getCompletions(); - assert.deepStrictEqual(items[0], { type: "title", text: "Buffers" }); - assert.ok(items[1].text.startsWith("2:")); - assert.ok(items[1].text.includes("title_site2")); - assert.ok(items[1].text.includes(server.url("/site2"))); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.ok(items[0].text.startsWith("2:")); + assert.ok(items[0].text.includes("title_site2")); }); }); @@ -104,9 +105,9 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("buffer /site2"); await eventually(async () => { - const items = await console.getCompletions(); - assert.deepStrictEqual(items[0], { type: "title", text: "Buffers" }); - assert.ok(items[1].text.startsWith("2:")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.ok(items[0].text.startsWith("2:")); }); }); @@ -115,10 +116,11 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("buffer 2"); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 2); - assert.deepStrictEqual(items[0], { type: "title", text: "Buffers" }); - assert.ok(items[1].text.startsWith("2:")); + const groups = await console.getCompletions(); + const items = groups[0].items; + + assert.strictEqual(items.length, 1); + assert.ok(items[0].text.startsWith("2:")); }); }); @@ -127,11 +129,12 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("bdelete site"); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 4); - assert.ok(items[1].text.includes("site3")); - assert.ok(items[2].text.includes("site4")); - assert.ok(items[3].text.includes("site5")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.strictEqual(items.length, 3); + assert.ok(items[0].text.includes("site3")); + assert.ok(items[1].text.includes("site4")); + assert.ok(items[2].text.includes("site5")); }); }); @@ -140,11 +143,12 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("bdeletes site"); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 4); - assert.ok(items[1].text.includes("site3")); - assert.ok(items[2].text.includes("site4")); - assert.ok(items[3].text.includes("site5")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.strictEqual(items.length, 3); + assert.ok(items[0].text.includes("site3")); + assert.ok(items[1].text.includes("site4")); + assert.ok(items[2].text.includes("site5")); }); }); @@ -153,13 +157,14 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("bdelete! site"); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 6); - assert.ok(items[1].text.includes("site1")); - assert.ok(items[2].text.includes("site2")); - assert.ok(items[3].text.includes("site3")); - assert.ok(items[4].text.includes("site4")); - assert.ok(items[5].text.includes("site5")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.strictEqual(items.length, 5); + assert.ok(items[0].text.includes("site1")); + assert.ok(items[1].text.includes("site2")); + assert.ok(items[2].text.includes("site3")); + assert.ok(items[3].text.includes("site4")); + assert.ok(items[4].text.includes("site5")); }); }); @@ -168,13 +173,14 @@ describe("completion on buffer/bdelete/bdeletes", () => { await console.inputKeys("bdeletes! site"); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 6); - assert.ok(items[1].text.includes("site1")); - assert.ok(items[2].text.includes("site2")); - assert.ok(items[3].text.includes("site3")); - assert.ok(items[4].text.includes("site4")); - assert.ok(items[5].text.includes("site5")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.strictEqual(items.length, 5); + assert.ok(items[0].text.includes("site1")); + assert.ok(items[1].text.includes("site2")); + assert.ok(items[2].text.includes("site3")); + assert.ok(items[3].text.includes("site4")); + assert.ok(items[4].text.includes("site5")); }); }); }); diff --git a/e2e/completion_open.test.ts b/e2e/completion_open.test.ts index cefb44f..7eef4c2 100644 --- a/e2e/completion_open.test.ts +++ b/e2e/completion_open.test.ts @@ -45,31 +45,13 @@ describe("completion on open/tabopen/winopen commands", () => { await console.inputKeys("open "); await eventually(async () => { - const completions = await console.getCompletions(); - assert.ok( - completions.find( - (x) => x.type === "title" && x.text === "Search Engines" - ) - ); - assert.ok( - completions.find((x) => x.type === "title" && x.text === "Bookmarks") - ); - assert.ok( - completions.find((x) => x.type === "title" && x.text === "History") - ); - }); - }); - - it('should filter items with URLs by keywords on "open" command', async () => { - const console = await page.showConsole(); - await console.inputKeys("open https://"); - - await eventually(async () => { - const completions = await console.getCompletions(); - const items = completions - .filter((x) => x.type === "item") - .map((x) => x.text); - assert.ok(items.every((x) => x.includes("https://"))); + const groups = await console.getCompletions(); + const titles = groups.map((group) => group.title); + assert.deepStrictEqual(titles, [ + "Search Engines", + "Bookmarks", + "History", + ]); }); }); @@ -78,11 +60,9 @@ describe("completion on open/tabopen/winopen commands", () => { await console.inputKeys("open getting"); await eventually(async () => { - const completions = await console.getCompletions(); - const items = completions - .filter((x) => x.type === "item") - .map((x) => x.text); - assert.ok(items.every((x) => x.toLowerCase().includes("getting"))); + const groups = await console.getCompletions(); + const items = groups.map((group) => group.items).flat(); + assert.ok(items.every((x) => x.text.toLowerCase().includes("getting"))); }); }); @@ -91,24 +71,20 @@ describe("completion on open/tabopen/winopen commands", () => { await console.inputKeys("tabopen getting"); await eventually(async () => { - const completions = await console.getCompletions(); - const items = completions - .filter((x) => x.type === "item") - .map((x) => x.text); - assert.ok(items.every((x) => x.includes("https://"))); + const groups = await console.getCompletions(); + const items = groups.map((group) => group.items).flat(); + assert.ok(items.every((x) => x.text.toLowerCase().includes("getting"))); }); }); it('should filter items with titles by keywords on "winopen" command', async () => { const console = await page.showConsole(); - await console.inputKeys("winopen https://"); + await console.inputKeys("winopen getting"); await eventually(async () => { - const completions = await console.getCompletions(); - const items = completions - .filter((x) => x.type === "item") - .map((x) => x.text); - assert.ok(items.every((x) => x.includes("https://"))); + const groups = await console.getCompletions(); + const items = groups.map((group) => group.items).flat(); + assert.ok(items.every((x) => x.text.toLowerCase().includes("getting"))); }); }); @@ -121,10 +97,8 @@ describe("completion on open/tabopen/winopen commands", () => { await console.inputKeys("open "); await eventually(async () => { - const completions = await console.getCompletions(); - const titles = completions - .filter((x) => x.type === "title") - .map((x) => x.text); + const groups = await console.getCompletions(); + const titles = groups.map((group) => group.title); assert.deepStrictEqual(titles, [ "Search Engines", "Bookmarks", @@ -141,10 +115,8 @@ describe("completion on open/tabopen/winopen commands", () => { await console.inputKeys("open "); await eventually(async () => { - const completions = await console.getCompletions(); - const titles = completions - .filter((x) => x.type === "title") - .map((x) => x.text); + const groups = await console.getCompletions(); + const titles = groups.map((group) => group.title); assert.deepStrictEqual(titles, [ "Bookmarks", "Search Engines", @@ -164,10 +136,8 @@ describe("completion on open/tabopen/winopen commands", () => { await console.inputKeys("open "); await eventually(async () => { - const completions = await console.getCompletions(); - const titles = completions - .filter((x) => x.type === "title") - .map((x) => x.text); + const groups = await console.getCompletions(); + const titles = groups.map((group) => group.title); assert.deepStrictEqual(titles, [ "Search Engines", "Bookmarks", @@ -188,10 +158,8 @@ describe("completion on open/tabopen/winopen commands", () => { await console.inputKeys("open "); await eventually(async () => { - const completions = await console.getCompletions(); - const titles = completions - .filter((x) => x.type === "title") - .map((x) => x.text); + const groups = await console.getCompletions(); + const titles = groups.map((group) => group.title); assert.deepStrictEqual(titles, [ "Bookmarks", "Search Engines", diff --git a/e2e/completion_set.test.ts b/e2e/completion_set.test.ts index 0a45ed3..929f649 100644 --- a/e2e/completion_set.test.ts +++ b/e2e/completion_set.test.ts @@ -33,14 +33,14 @@ describe("completion on set commands", () => { await console.inputKeys("set "); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 6); - assert.deepStrictEqual(items[0], { type: "title", text: "Properties" }); - assert.ok(items[1].text.startsWith("hintchars")); - assert.ok(items[2].text.startsWith("smoothscroll")); - assert.ok(items[3].text.startsWith("nosmoothscroll")); - assert.ok(items[4].text.startsWith("complete")); - assert.ok(items[5].text.startsWith("colorscheme")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.strictEqual(items.length, 5); + assert.ok(items[0].text.startsWith("hintchars")); + assert.ok(items[1].text.startsWith("smoothscroll")); + assert.ok(items[2].text.startsWith("nosmoothscroll")); + assert.ok(items[3].text.startsWith("complete")); + assert.ok(items[4].text.startsWith("colorscheme")); }); }); @@ -49,9 +49,10 @@ describe("completion on set commands", () => { await console.inputKeys("set no"); await eventually(async () => { - const items = await console.getCompletions(); - assert.strictEqual(items.length, 2); - assert.ok(items[1].text.includes("nosmoothscroll")); + const groups = await console.getCompletions(); + const items = groups[0].items; + assert.strictEqual(items.length, 1); + assert.ok(items[0].text.includes("nosmoothscroll")); }); }); }); diff --git a/e2e/lib/Console.ts b/e2e/lib/Console.ts index 2d397c6..4d017cc 100644 --- a/e2e/lib/Console.ts +++ b/e2e/lib/Console.ts @@ -1,7 +1,7 @@ import { WebDriver, By, Key } from "selenium-webdriver"; export type CompletionGroups = { - name: string; + title: string; items: Array; }; @@ -34,16 +34,12 @@ export class Console { } async getErrorMessage(): Promise { - const p = await this.webdriver.findElement( - By.css(".vimvixen-console-error") - ); + const p = await this.webdriver.findElement(By.css("[role=alert]")); return p.getText(); } async getInformationMessage(): Promise { - const p = await this.webdriver.findElement( - By.css(".vimvixen-console-info") - ); + const p = await this.webdriver.findElement(By.css("[role=status]")); return p.getText(); } @@ -52,29 +48,42 @@ export class Console { await input.sendKeys(...keys); } - getCompletions(): Promise { + getCompletions(): Promise { return this.webdriver.executeScript(() => { const groups = document.querySelectorAll("[role=group]"); if (groups.length === 0) { throw new Error("completion items not found"); } - return Array.from(groups).map((group) => ({ - name: group.textContent!.trim(), - items: Array.from(group.querySelectorAll("[role=menuitem]")).map( - (item) => ({ - text: item.textContent!.trim(), + return Array.from(groups).map((group) => { + const describedby = group.getAttribute("aria-describedby") as string; + const title = document.getElementById(describedby)!; + const items = group.querySelectorAll("[role=menuitem]"); + + return { + title: title.textContent!.trim(), + items: Array.from(items).map((item) => ({ + text: document.getElementById( + item.getAttribute("aria-labelledby")! + )!.textContent, highlight: item.getAttribute("aria-selected") === "true", - }) - ), - })); + })), + }; + }); }); } async getTheme(): Promise { - const wrapper = await this.webdriver.findElement(By.css("div[data-theme]")); - const theme = await wrapper.getAttribute("data-theme"); - return theme; + const color = (await this.webdriver.executeScript(() => { + const input = document.querySelector("input")!; + return window.getComputedStyle(input).backgroundColor; + })) as string; + if (color === "rgb(5, 32, 39)") { + return "dark"; + } else if (color === "rgb(255, 255, 255)") { + return "light"; + } + throw new Error(`unknown input color: ${color}`); } async close(): Promise { diff --git a/src/console/components/console/CompletionItem.tsx b/src/console/components/console/CompletionItem.tsx index 76db5b5..46cd95c 100644 --- a/src/console/components/console/CompletionItem.tsx +++ b/src/console/components/console/CompletionItem.tsx @@ -49,8 +49,12 @@ interface Props { const CompletionItem: React.FC & Props> = ( props ) => ( - - {props.caption} + + {props.caption} {props.url} ); diff --git a/tsconfig.json b/tsconfig.json index f3a6a33..9d56c01 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "es2017", "module": "commonjs", - "lib": ["es6", "dom", "es2017"], + "lib": ["es6", "dom", "esnext"], "allowJs": true, "checkJs": false, "jsx": "react", -- cgit v1.2.3 From 35da038ba324a32eed63c04e19fd31d7137880a9 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 21 Sep 2020 12:46:00 +0900 Subject: Fix console icon --- src/console/components/console/CompletionItem.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/console/components/console/CompletionItem.tsx b/src/console/components/console/CompletionItem.tsx index 46cd95c..5f2f9f6 100644 --- a/src/console/components/console/CompletionItem.tsx +++ b/src/console/components/console/CompletionItem.tsx @@ -6,7 +6,7 @@ const Container = styled.li<{ icon: string; highlight: boolean; }>` - backgroundimage: ${({ icon }) => "url(" + icon + ")"}; + background-image: ${({ icon }) => "url(" + icon + ")"}; background-color: ${({ highlight, theme }) => highlight ? theme.completionSelectedBackground @@ -16,7 +16,7 @@ const Container = styled.li<{ ? theme.completionSelectedForeground : theme.completionItemForeground}; display: ${({ shown }) => (shown ? "display" : "none")}; - padding-left: 1.5rem; + padding-left: 1.8rem; background-position: 0 center; background-size: contain; background-repeat: no-repeat; -- cgit v1.2.3 From 9bba3ed79123affc8e557cf4211df51bd375742c Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 21 Sep 2020 12:52:35 +0900 Subject: Remove unused className --- e2e/lib/Page.ts | 4 +--- src/console/components/console/Input.tsx | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/e2e/lib/Page.ts b/e2e/lib/Page.ts index 85bda8d..6531f19 100644 --- a/e2e/lib/Page.ts +++ b/e2e/lib/Page.ts @@ -46,9 +46,7 @@ export default class Page { await this.sendKeys(":"); await this.webdriver.wait(until.elementIsVisible(iframe)); await this.webdriver.switchTo().frame(0); - await this.webdriver.wait( - until.elementLocated(By.css("input.vimvixen-console-command-input")) - ); + await this.webdriver.wait(until.elementLocated(By.css("input"))); return new Console(this.webdriver); } diff --git a/src/console/components/console/Input.tsx b/src/console/components/console/Input.tsx index 61fbc46..448b096 100644 --- a/src/console/components/console/Input.tsx +++ b/src/console/components/console/Input.tsx @@ -53,7 +53,6 @@ class Input extends React.Component { {prompt}