parent
bacf83a320
commit
1ba1660269
15 changed files with 423 additions and 181 deletions
@ -1,100 +0,0 @@ |
|||||||
//
|
|
||||||
// window.find(aString, aCaseSensitive, aBackwards, aWrapAround,
|
|
||||||
// aWholeWord, aSearchInFrames);
|
|
||||||
//
|
|
||||||
// NOTE: window.find is not standard API
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/find
|
|
||||||
|
|
||||||
import * as messages from '../../shared/messages'; |
|
||||||
import * as actions from './index'; |
|
||||||
import * as consoleFrames from '../console-frames'; |
|
||||||
|
|
||||||
interface MyWindow extends Window { |
|
||||||
find( |
|
||||||
aString: string, |
|
||||||
aCaseSensitive?: boolean, |
|
||||||
aBackwards?: boolean, |
|
||||||
aWrapAround?: boolean, |
|
||||||
aWholeWord?: boolean, |
|
||||||
aSearchInFrames?: boolean, |
|
||||||
aShowDialog?: boolean): boolean; |
|
||||||
} |
|
||||||
|
|
||||||
// eslint-disable-next-line no-var, vars-on-top, init-declarations
|
|
||||||
declare var window: MyWindow; |
|
||||||
|
|
||||||
const find = (str: string, backwards: boolean): boolean => { |
|
||||||
let caseSensitive = false; |
|
||||||
let wrapScan = true; |
|
||||||
|
|
||||||
|
|
||||||
// NOTE: aWholeWord dows not implemented, and aSearchInFrames does not work
|
|
||||||
// because of same origin policy
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-extra-parens
|
|
||||||
let found = window.find(str, caseSensitive, backwards, wrapScan); |
|
||||||
if (found) { |
|
||||||
return found; |
|
||||||
} |
|
||||||
let sel = window.getSelection(); |
|
||||||
if (sel) { |
|
||||||
sel.removeAllRanges(); |
|
||||||
} |
|
||||||
|
|
||||||
// eslint-disable-next-line no-extra-parens
|
|
||||||
return window.find(str, caseSensitive, backwards, wrapScan); |
|
||||||
}; |
|
||||||
|
|
||||||
// eslint-disable-next-line max-statements
|
|
||||||
const findNext = async( |
|
||||||
currentKeyword: string, reset: boolean, backwards: boolean, |
|
||||||
): Promise<actions.FindAction> => { |
|
||||||
if (reset) { |
|
||||||
let sel = window.getSelection(); |
|
||||||
if (sel) { |
|
||||||
sel.removeAllRanges(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
let keyword = currentKeyword; |
|
||||||
if (currentKeyword) { |
|
||||||
browser.runtime.sendMessage({ |
|
||||||
type: messages.FIND_SET_KEYWORD, |
|
||||||
keyword: currentKeyword, |
|
||||||
}); |
|
||||||
} else { |
|
||||||
keyword = await browser.runtime.sendMessage({ |
|
||||||
type: messages.FIND_GET_KEYWORD, |
|
||||||
}); |
|
||||||
} |
|
||||||
if (!keyword) { |
|
||||||
await consoleFrames.postError('No previous search keywords'); |
|
||||||
return { type: actions.NOOP }; |
|
||||||
} |
|
||||||
let found = find(keyword, backwards); |
|
||||||
if (found) { |
|
||||||
consoleFrames.postInfo('Pattern found: ' + keyword); |
|
||||||
} else { |
|
||||||
consoleFrames.postError('Pattern not found: ' + keyword); |
|
||||||
} |
|
||||||
|
|
||||||
return { |
|
||||||
type: actions.FIND_SET_KEYWORD, |
|
||||||
keyword, |
|
||||||
found, |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
const next = ( |
|
||||||
currentKeyword: string, reset: boolean, |
|
||||||
): Promise<actions.FindAction> => { |
|
||||||
return findNext(currentKeyword, reset, false); |
|
||||||
}; |
|
||||||
|
|
||||||
const prev = ( |
|
||||||
currentKeyword: string, reset: boolean, |
|
||||||
): Promise<actions.FindAction> => { |
|
||||||
return findNext(currentKeyword, reset, true); |
|
||||||
}; |
|
||||||
|
|
||||||
export { next, prev }; |
|
@ -0,0 +1,30 @@ |
|||||||
|
import * as messages from '../../shared/messages'; |
||||||
|
|
||||||
|
export default interface ConsoleClient { |
||||||
|
info(text: string): Promise<void>; |
||||||
|
error(text: string): Promise<void>; |
||||||
|
|
||||||
|
// eslint-disable-next-line semi
|
||||||
|
} |
||||||
|
|
||||||
|
export class ConsoleClientImpl implements ConsoleClient { |
||||||
|
async info(text: string): Promise<void> { |
||||||
|
await browser.runtime.sendMessage({ |
||||||
|
type: messages.CONSOLE_FRAME_MESSAGE, |
||||||
|
message: { |
||||||
|
type: messages.CONSOLE_SHOW_INFO, |
||||||
|
text, |
||||||
|
}, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async error(text: string): Promise<void> { |
||||||
|
await browser.runtime.sendMessage({ |
||||||
|
type: messages.CONSOLE_FRAME_MESSAGE, |
||||||
|
message: { |
||||||
|
type: messages.CONSOLE_SHOW_ERROR, |
||||||
|
text, |
||||||
|
}, |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
import * as messages from '../../shared/messages'; |
||||||
|
|
||||||
|
export default interface FindClient { |
||||||
|
getGlobalLastKeyword(): Promise<string | null>; |
||||||
|
|
||||||
|
setGlobalLastKeyword(keyword: string): Promise<void>; |
||||||
|
|
||||||
|
// eslint-disable-next-line semi
|
||||||
|
} |
||||||
|
|
||||||
|
export class FindClientImpl implements FindClient { |
||||||
|
async getGlobalLastKeyword(): Promise<string | null> { |
||||||
|
let keyword = await browser.runtime.sendMessage({ |
||||||
|
type: messages.FIND_GET_KEYWORD, |
||||||
|
}); |
||||||
|
return keyword as string; |
||||||
|
} |
||||||
|
|
||||||
|
async setGlobalLastKeyword(keyword: string): Promise<void> { |
||||||
|
await browser.runtime.sendMessage({ |
||||||
|
type: messages.FIND_SET_KEYWORD, |
||||||
|
keyword: keyword, |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
import ConsoleClient, { ConsoleClientImpl } from '../client/ConsoleClient'; |
||||||
|
|
||||||
|
export default interface FindPresenter { |
||||||
|
find(keyword: string, backwards: boolean): boolean; |
||||||
|
|
||||||
|
clearSelection(): void; |
||||||
|
|
||||||
|
// eslint-disable-next-line semi
|
||||||
|
} |
||||||
|
|
||||||
|
// window.find(aString, aCaseSensitive, aBackwards, aWrapAround,
|
||||||
|
// aWholeWord, aSearchInFrames);
|
||||||
|
//
|
||||||
|
// NOTE: window.find is not standard API
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Window/find
|
||||||
|
interface MyWindow extends Window { |
||||||
|
find( |
||||||
|
aString: string, |
||||||
|
aCaseSensitive?: boolean, |
||||||
|
aBackwards?: boolean, |
||||||
|
aWrapAround?: boolean, |
||||||
|
aWholeWord?: boolean, |
||||||
|
aSearchInFrames?: boolean, |
||||||
|
aShowDialog?: boolean): boolean; |
||||||
|
} |
||||||
|
|
||||||
|
// eslint-disable-next-line no-var, vars-on-top, init-declarations
|
||||||
|
declare var window: MyWindow; |
||||||
|
|
||||||
|
export class FindPresenterImpl implements FindPresenter { |
||||||
|
private consoleClient: ConsoleClient; |
||||||
|
|
||||||
|
constructor({ consoleClient = new ConsoleClientImpl() } = {}) { |
||||||
|
this.consoleClient = consoleClient; |
||||||
|
} |
||||||
|
|
||||||
|
find(keyword: string, backwards: boolean): boolean { |
||||||
|
let caseSensitive = false; |
||||||
|
let wrapScan = true; |
||||||
|
|
||||||
|
|
||||||
|
// NOTE: aWholeWord dows not implemented, and aSearchInFrames does not work
|
||||||
|
// because of same origin policy
|
||||||
|
let found = window.find(keyword, caseSensitive, backwards, wrapScan); |
||||||
|
if (found) { |
||||||
|
return found; |
||||||
|
} |
||||||
|
this.clearSelection(); |
||||||
|
|
||||||
|
return window.find(keyword, caseSensitive, backwards, wrapScan); |
||||||
|
} |
||||||
|
|
||||||
|
clearSelection(): void { |
||||||
|
let sel = window.getSelection(); |
||||||
|
if (sel) { |
||||||
|
sel.removeAllRanges(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,25 +0,0 @@ |
|||||||
import * as actions from '../actions'; |
|
||||||
|
|
||||||
export interface State { |
|
||||||
keyword: string | null; |
|
||||||
found: boolean; |
|
||||||
} |
|
||||||
|
|
||||||
const defaultState: State = { |
|
||||||
keyword: null, |
|
||||||
found: false, |
|
||||||
}; |
|
||||||
|
|
||||||
export default function reducer( |
|
||||||
state: State = defaultState, |
|
||||||
action: actions.FindAction, |
|
||||||
): State { |
|
||||||
switch (action.type) { |
|
||||||
case actions.FIND_SET_KEYWORD: |
|
||||||
return { ...state, |
|
||||||
keyword: action.keyword, |
|
||||||
found: action.found, }; |
|
||||||
default: |
|
||||||
return state; |
|
||||||
} |
|
||||||
} |
|
@ -1,17 +1,15 @@ |
|||||||
import { combineReducers } from 'redux'; |
import { combineReducers } from 'redux'; |
||||||
import find, { State as FindState } from './find'; |
|
||||||
import input, { State as InputState } from './input'; |
import input, { State as InputState } from './input'; |
||||||
import followController, { State as FollowControllerState } |
import followController, { State as FollowControllerState } |
||||||
from './follow-controller'; |
from './follow-controller'; |
||||||
import mark, { State as MarkState } from './mark'; |
import mark, { State as MarkState } from './mark'; |
||||||
|
|
||||||
export interface State { |
export interface State { |
||||||
find: FindState; |
|
||||||
input: InputState; |
input: InputState; |
||||||
followController: FollowControllerState; |
followController: FollowControllerState; |
||||||
mark: MarkState; |
mark: MarkState; |
||||||
} |
} |
||||||
|
|
||||||
export default combineReducers({ |
export default combineReducers({ |
||||||
find, input, followController, mark, |
input, followController, mark, |
||||||
}); |
}); |
||||||
|
@ -0,0 +1,19 @@ |
|||||||
|
export default interface FindRepository { |
||||||
|
getLastKeyword(): string | null; |
||||||
|
|
||||||
|
setLastKeyword(keyword: string): void; |
||||||
|
|
||||||
|
// eslint-disable-next-line semi
|
||||||
|
} |
||||||
|
|
||||||
|
let current: string | null = null; |
||||||
|
|
||||||
|
export class FindRepositoryImpl implements FindRepository { |
||||||
|
getLastKeyword(): string | null { |
||||||
|
return current; |
||||||
|
} |
||||||
|
|
||||||
|
setLastKeyword(keyword: string): void { |
||||||
|
current = keyword; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
import FindPresenter, { FindPresenterImpl } from '../presenters/FindPresenter'; |
||||||
|
import FindRepository, { FindRepositoryImpl } |
||||||
|
from '../repositories/FindRepository'; |
||||||
|
import FindClient, { FindClientImpl } from '../client/FindClient'; |
||||||
|
import ConsoleClient, { ConsoleClientImpl } from '../client/ConsoleClient'; |
||||||
|
|
||||||
|
export default class FindUseCase { |
||||||
|
private presenter: FindPresenter; |
||||||
|
|
||||||
|
private repository: FindRepository; |
||||||
|
|
||||||
|
private client: FindClient; |
||||||
|
|
||||||
|
private consoleClient: ConsoleClient; |
||||||
|
|
||||||
|
constructor({ |
||||||
|
presenter = new FindPresenterImpl() as FindPresenter, |
||||||
|
repository = new FindRepositoryImpl(), |
||||||
|
client = new FindClientImpl(), |
||||||
|
consoleClient = new ConsoleClientImpl(), |
||||||
|
} = {}) { |
||||||
|
this.presenter = presenter; |
||||||
|
this.repository = repository; |
||||||
|
this.client = client; |
||||||
|
this.consoleClient = consoleClient; |
||||||
|
} |
||||||
|
|
||||||
|
async startFind(keyword: string | null): Promise<void> { |
||||||
|
this.presenter.clearSelection(); |
||||||
|
if (keyword) { |
||||||
|
this.saveKeyword(keyword); |
||||||
|
} else { |
||||||
|
let lastKeyword = await this.getKeyword(); |
||||||
|
if (!lastKeyword) { |
||||||
|
return this.showNoLastKeywordError(); |
||||||
|
} |
||||||
|
this.saveKeyword(lastKeyword); |
||||||
|
} |
||||||
|
return this.findNext(); |
||||||
|
} |
||||||
|
|
||||||
|
findNext(): Promise<void> { |
||||||
|
return this.findNextPrev(false); |
||||||
|
} |
||||||
|
|
||||||
|
findPrev(): Promise<void> { |
||||||
|
return this.findNextPrev(true); |
||||||
|
} |
||||||
|
|
||||||
|
private async findNextPrev( |
||||||
|
backwards: boolean, |
||||||
|
): Promise<void> { |
||||||
|
let keyword = await this.getKeyword(); |
||||||
|
if (!keyword) { |
||||||
|
return this.showNoLastKeywordError(); |
||||||
|
} |
||||||
|
let found = this.presenter.find(keyword, backwards); |
||||||
|
if (found) { |
||||||
|
this.consoleClient.info('Pattern found: ' + keyword); |
||||||
|
} else { |
||||||
|
this.consoleClient.error('Pattern not found: ' + keyword); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private async getKeyword(): Promise<string | null> { |
||||||
|
let keyword = this.repository.getLastKeyword(); |
||||||
|
if (!keyword) { |
||||||
|
keyword = await this.client.getGlobalLastKeyword(); |
||||||
|
} |
||||||
|
return keyword; |
||||||
|
} |
||||||
|
|
||||||
|
private async saveKeyword(keyword: string): Promise<void> { |
||||||
|
this.repository.setLastKeyword(keyword); |
||||||
|
await this.client.setGlobalLastKeyword(keyword); |
||||||
|
} |
||||||
|
|
||||||
|
private async showNoLastKeywordError(): Promise<void> { |
||||||
|
await this.consoleClient.error('No previous search keywords'); |
||||||
|
} |
||||||
|
} |
@ -1,22 +0,0 @@ |
|||||||
import * as actions from 'content/actions'; |
|
||||||
import findReducer from 'content/reducers/find'; |
|
||||||
|
|
||||||
describe("find reducer", () => { |
|
||||||
it('return the initial state', () => { |
|
||||||
let state = findReducer(undefined, {}); |
|
||||||
expect(state).to.have.property('keyword', null); |
|
||||||
expect(state).to.have.property('found', false); |
|
||||||
}); |
|
||||||
|
|
||||||
it('return next state for FIND_SET_KEYWORD', () => { |
|
||||||
let action = { |
|
||||||
type: actions.FIND_SET_KEYWORD, |
|
||||||
keyword: 'xyz', |
|
||||||
found: true, |
|
||||||
}; |
|
||||||
let state = findReducer({}, action); |
|
||||||
|
|
||||||
expect(state.keyword).is.equal('xyz'); |
|
||||||
expect(state.found).to.be.true; |
|
||||||
}); |
|
||||||
}); |
|
@ -0,0 +1,15 @@ |
|||||||
|
import { FindRepositoryImpl } from '../../../src/content/repositories/FindRepository'; |
||||||
|
import { expect } from 'chai'; |
||||||
|
|
||||||
|
describe('FindRepositoryImpl', () => { |
||||||
|
it('updates and gets last keyword', () => { |
||||||
|
let sut = new FindRepositoryImpl(); |
||||||
|
|
||||||
|
expect(sut.getLastKeyword()).to.be.null; |
||||||
|
|
||||||
|
sut.setLastKeyword('monkey'); |
||||||
|
|
||||||
|
expect(sut.getLastKeyword()).to.equal('monkey'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
@ -0,0 +1,184 @@ |
|||||||
|
import FindRepository from '../../../src/content/repositories/FindRepository'; |
||||||
|
import FindPresenter from '../../../src/content/presenters/FindPresenter'; |
||||||
|
import ConsoleClient from '../../../src/content/client/ConsoleClient'; |
||||||
|
import FindClient from '../../../src/content/client/FindClient'; |
||||||
|
import FindUseCase from '../../../src/content/usecases/FindUseCase'; |
||||||
|
import { expect } from 'chai'; |
||||||
|
|
||||||
|
class MockFindRepository implements FindRepository { |
||||||
|
public keyword: string | null; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.keyword = null; |
||||||
|
} |
||||||
|
|
||||||
|
getLastKeyword(): string | null { |
||||||
|
return this.keyword; |
||||||
|
} |
||||||
|
|
||||||
|
setLastKeyword(keyword: string): void { |
||||||
|
this.keyword = keyword; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class MockFindPresenter implements FindPresenter { |
||||||
|
public document: string; |
||||||
|
|
||||||
|
public highlighted: boolean; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.document = ''; |
||||||
|
this.highlighted = false; |
||||||
|
} |
||||||
|
|
||||||
|
find(keyword: string, _backward: boolean): boolean { |
||||||
|
let found = this.document.includes(keyword); |
||||||
|
this.highlighted = found; |
||||||
|
return found; |
||||||
|
} |
||||||
|
|
||||||
|
clearSelection(): void { |
||||||
|
this.highlighted = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class MockFindClient implements FindClient { |
||||||
|
public keyword: string | null; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.keyword = null; |
||||||
|
} |
||||||
|
|
||||||
|
getGlobalLastKeyword(): Promise<string | null> { |
||||||
|
return Promise.resolve(this.keyword); |
||||||
|
} |
||||||
|
|
||||||
|
setGlobalLastKeyword(keyword: string): Promise<void> { |
||||||
|
this.keyword = keyword; |
||||||
|
return Promise.resolve(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class MockConsoleClient implements ConsoleClient { |
||||||
|
public isError: boolean; |
||||||
|
|
||||||
|
public text: string; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.isError = false; |
||||||
|
this.text = ''; |
||||||
|
} |
||||||
|
|
||||||
|
info(text: string): Promise<void> { |
||||||
|
this.isError = false; |
||||||
|
this.text = text; |
||||||
|
return Promise.resolve(); |
||||||
|
} |
||||||
|
|
||||||
|
error(text: string): Promise<void> { |
||||||
|
this.isError = true; |
||||||
|
this.text = text; |
||||||
|
return Promise.resolve(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
describe('FindUseCase', () => { |
||||||
|
let repository: MockFindRepository; |
||||||
|
let presenter: MockFindPresenter; |
||||||
|
let client: MockFindClient; |
||||||
|
let consoleClient: MockConsoleClient; |
||||||
|
let sut: FindUseCase; |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
repository = new MockFindRepository(); |
||||||
|
presenter = new MockFindPresenter(); |
||||||
|
client = new MockFindClient(); |
||||||
|
consoleClient = new MockConsoleClient(); |
||||||
|
sut = new FindUseCase({ repository, presenter, client, consoleClient }); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#startFind', () => { |
||||||
|
it('find next by ketword', async() => { |
||||||
|
presenter.document = 'monkey punch'; |
||||||
|
|
||||||
|
await sut.startFind('monkey'); |
||||||
|
|
||||||
|
expect(await presenter.highlighted).to.be.true; |
||||||
|
expect(await consoleClient.text).to.equal('Pattern found: monkey'); |
||||||
|
expect(await repository.getLastKeyword()).to.equal('monkey'); |
||||||
|
expect(await client.getGlobalLastKeyword()).to.equal('monkey'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('find next by last keyword', async() => { |
||||||
|
presenter.document = 'gorilla kick'; |
||||||
|
repository.keyword = 'gorilla'; |
||||||
|
|
||||||
|
await sut.startFind(null); |
||||||
|
|
||||||
|
expect(await presenter.highlighted).to.be.true; |
||||||
|
expect(await consoleClient.text).to.equal('Pattern found: gorilla'); |
||||||
|
expect(await repository.getLastKeyword()).to.equal('gorilla'); |
||||||
|
expect(await client.getGlobalLastKeyword()).to.equal('gorilla'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('find next by global last keyword', async() => { |
||||||
|
presenter.document = 'chimpanzee typing'; |
||||||
|
|
||||||
|
repository.keyword = null; |
||||||
|
client.keyword = 'chimpanzee'; |
||||||
|
|
||||||
|
await sut.startFind(null); |
||||||
|
|
||||||
|
expect(await presenter.highlighted).to.be.true; |
||||||
|
expect(await consoleClient.text).to.equal('Pattern found: chimpanzee'); |
||||||
|
expect(await repository.getLastKeyword()).to.equal('chimpanzee'); |
||||||
|
expect(await client.getGlobalLastKeyword()).to.equal('chimpanzee'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('find not found error', async() => { |
||||||
|
presenter.document = 'zoo'; |
||||||
|
|
||||||
|
await sut.startFind('giraffe'); |
||||||
|
|
||||||
|
expect(await presenter.highlighted).to.be.false; |
||||||
|
expect(await consoleClient.text).to.equal('Pattern not found: giraffe'); |
||||||
|
expect(await repository.getLastKeyword()).to.equal('giraffe'); |
||||||
|
expect(await client.getGlobalLastKeyword()).to.equal('giraffe'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('show errors when no last keywords', async() => { |
||||||
|
repository.keyword = null; |
||||||
|
client.keyword = null; |
||||||
|
|
||||||
|
await sut.startFind(null); |
||||||
|
|
||||||
|
expect(await consoleClient.text).to.equal('No previous search keywords'); |
||||||
|
expect(await consoleClient.isError).to.be.true; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#findNext', () => { |
||||||
|
it('finds by last keyword', async() => { |
||||||
|
presenter.document = 'monkey punch'; |
||||||
|
repository.keyword = 'monkey'; |
||||||
|
|
||||||
|
await sut.findNext(); |
||||||
|
|
||||||
|
expect(await presenter.highlighted).to.be.true; |
||||||
|
expect(await consoleClient.text).to.equal('Pattern found: monkey'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('show errors when no last keywords', async() => { |
||||||
|
repository.keyword = null; |
||||||
|
client.keyword = null; |
||||||
|
|
||||||
|
await sut.findNext(); |
||||||
|
|
||||||
|
expect(await consoleClient.text).to.equal('No previous search keywords'); |
||||||
|
expect(await consoleClient.isError).to.be.true; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#findPrev', () => { |
||||||
|
}); |
||||||
|
}); |
Reference in new issue