From 01242a2f0d174b4bf8b51fd5627edced465757e9 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 23 Sep 2021 12:44:49 +0900 Subject: Search a content from frames successfully loaded --- src/background/operators/impls/FindNextOperator.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/background/operators/impls/FindNextOperator.ts') diff --git a/src/background/operators/impls/FindNextOperator.ts b/src/background/operators/impls/FindNextOperator.ts index 241f71d..2aed9fb 100644 --- a/src/background/operators/impls/FindNextOperator.ts +++ b/src/background/operators/impls/FindNextOperator.ts @@ -3,7 +3,7 @@ import TabPresenter from "../../presenters/TabPresenter"; import FindRepository from "../../repositories/FindRepository"; import FindClient from "../../clients/FindClient"; import ConsoleClient from "../../infrastructures/ConsoleClient"; -import FramePresenter from "../../presenters/FramePresenter"; +import ReadyFrameRepository from "../../repositories/ReadyFrameRepository"; export default class FindNextOperator implements Operator { constructor( @@ -11,7 +11,7 @@ export default class FindNextOperator implements Operator { private readonly findRepository: FindRepository, private readonly findClient: FindClient, private readonly consoleClient: ConsoleClient, - private readonly framePresenter: FramePresenter + private readonly frameRepository: ReadyFrameRepository ) {} async run(): Promise { @@ -65,7 +65,12 @@ export default class FindNextOperator implements Operator { const keyword = await this.findRepository.getGlobalKeyword(); if (keyword) { - const frameIds = await this.framePresenter.getAllFrameIds(tabId); + const frameIds = await this.frameRepository.getFrameIds(tabId); + if (typeof frameIds === "undefined") { + // No frames are ready + return; + } + for (const frameId of frameIds) { await this.findClient.clearSelection(tabId, frameId); } -- cgit v1.2.3 From b72728bdabf140c77f165b35813595dcaa060eea Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 23 Sep 2021 23:23:55 +0900 Subject: Create find targets by port connections --- src/background/Application.ts | 41 ++++++---- src/background/infrastructures/FindPortListener.ts | 23 ++++++ src/background/operators/impls/FindNextOperator.ts | 94 ++++++++++------------ src/background/operators/impls/FindPrevOperator.ts | 94 ++++++++++------------ src/background/repositories/FindRepository.ts | 3 +- .../repositories/ReadyFrameRepository.ts | 22 ++++- src/background/usecases/StartFindUseCase.ts | 11 +-- src/content/Application.ts | 16 +++- test/background/mock/MockReadyFrameRepository.ts | 4 + .../operators/impls/FindNextOperator.test.ts | 24 +++--- .../operators/impls/FindPrevOperator.test.ts | 24 +++--- .../background/repositories/FindRepository.test.ts | 4 +- test/background/usecases/StartFindUseCase.test.ts | 8 +- 13 files changed, 207 insertions(+), 161 deletions(-) create mode 100644 src/background/infrastructures/FindPortListener.ts (limited to 'src/background/operators/impls/FindNextOperator.ts') diff --git a/src/background/Application.ts b/src/background/Application.ts index 87865e6..c7bcc42 100644 --- a/src/background/Application.ts +++ b/src/background/Application.ts @@ -1,5 +1,6 @@ import { injectable, inject } from "tsyringe"; import ContentMessageListener from "./infrastructures/ContentMessageListener"; +import FindPortListener from "./infrastructures/FindPortListener"; import SettingController from "./controllers/SettingController"; import VersionController from "./controllers/VersionController"; import SettingRepository from "./repositories/SettingRepository"; @@ -20,6 +21,11 @@ export default class Application { private readonly frameRepository: ReadyFrameRepository ) {} + private readonly findPortListener = new FindPortListener( + this.onFindPortConnect.bind(this), + this.onFindPortDisconnect.bind(this) + ); + run() { this.settingController.reload(); @@ -35,24 +41,31 @@ export default class Application { } this.versionController.notify(); }); - browser.webNavigation.onCompleted.addListener((detail) => { - // The console iframe embedded by Vim-Vixen has url starting with - // 'moz-extensions://'. The add-on should ignore it from search targets. - // - // When a browser blocks to load an iframe by x-frame options or a - // content security policy, the URL begins with 'about:neterror', and - // a background script fails to send a message to iframe. - if ( - detail.url.startsWith("http://") || - detail.url.startsWith("https://") - ) { - this.frameRepository.addFrameId(detail.tabId, detail.frameId); - } - }); this.contentMessageListener.run(); this.syncSettingRepository.onChange(() => { this.settingController.reload(); }); + this.findPortListener.run(); + } + + private onFindPortConnect(port: browser.runtime.Port) { + const tabId = port.sender?.tab?.id; + const frameId = port.sender?.frameId; + if (typeof tabId === "undefined" || typeof frameId === "undefined") { + return; + } + + this.frameRepository.addFrameId(tabId, frameId); + } + + private onFindPortDisconnect(port: browser.runtime.Port) { + const tabId = port.sender?.tab?.id; + const frameId = port.sender?.frameId; + if (typeof tabId === "undefined" || typeof frameId === "undefined") { + return; + } + + this.frameRepository.removeFrameId(tabId, frameId); } } diff --git a/src/background/infrastructures/FindPortListener.ts b/src/background/infrastructures/FindPortListener.ts new file mode 100644 index 0000000..ca82439 --- /dev/null +++ b/src/background/infrastructures/FindPortListener.ts @@ -0,0 +1,23 @@ +import { injectable } from "tsyringe"; + +type OnConnectFunc = (port: browser.runtime.Port) => void; +type OnDisconnectFunc = (port: browser.runtime.Port) => void; + +@injectable() +export default class FindPortListener { + constructor( + private readonly onConnect: OnConnectFunc, + private readonly onDisconnect: OnDisconnectFunc + ) {} + + run(): void { + browser.runtime.onConnect.addListener((port) => { + if (port.name !== "vimvixen-find") { + return; + } + + port.onDisconnect.addListener(this.onDisconnect); + this.onConnect(port); + }); + } +} diff --git a/src/background/operators/impls/FindNextOperator.ts b/src/background/operators/impls/FindNextOperator.ts index 2aed9fb..99f1759 100644 --- a/src/background/operators/impls/FindNextOperator.ts +++ b/src/background/operators/impls/FindNextOperator.ts @@ -21,72 +21,64 @@ export default class FindNextOperator implements Operator { return; } + const frameIds = await this.frameRepository.getFrameIds(tabId); + if (typeof frameIds === "undefined") { + // No frames are ready + return; + } + const state = await this.findRepository.getLocalState(tabId); if (state) { - // Start to find the keyword from the current frame which last found on, - // and concat it to end of frame ids to perform a wrap-search - // - // ,- keyword should be in this frame - // | - // [100, 101, 0, 100] - // | - // `- continue from frame id 100 - // - const targetFrameIds = state.frameIds - .slice(state.framePos) - .concat( - state.frameIds.slice(0, state.framePos), - state.frameIds[state.framePos] - ); + const framePos = frameIds.indexOf(state.frameId); + if (framePos !== -1) { + // Start to find the keyword from the current frame which last found on, + // and concat it to end of frame ids to perform a wrap-search + // + // ,- keyword should be in this frame + // | + // [100, 101, 0, 100] + // | + // `- continue from frame id 100 + // + const targetFrameIds = frameIds + .slice(framePos) + .concat(frameIds.slice(0, framePos), frameIds[framePos]); - for (let i = 0; i < targetFrameIds.length; ++i) { - const found = await this.findClient.findNext( + for (const frameId of targetFrameIds) { + const found = await this.findClient.findNext( + tabId, + frameId, + state.keyword + ); + if (found) { + this.findRepository.setLocalState(tabId, { + keyword: state.keyword, + frameId, + }); + return; + } + this.findClient.clearSelection(tabId, frameId); + } + + // The keyword is gone. + this.consoleClient.showError( tabId, - targetFrameIds[i], - state.keyword + "Pattern not found: " + state.keyword ); - if (found) { - this.findRepository.setLocalState(tabId, { - ...state, - framePos: (i + state.framePos) % state.frameIds.length, // save current frame position or first - }); - return; - } - this.findClient.clearSelection(tabId, targetFrameIds[i]); + return; } - - // The keyword is gone. - this.consoleClient.showError( - tabId, - "Pattern not found: " + state.keyword - ); - return; } const keyword = await this.findRepository.getGlobalKeyword(); if (keyword) { - const frameIds = await this.frameRepository.getFrameIds(tabId); - if (typeof frameIds === "undefined") { - // No frames are ready - return; - } - for (const frameId of frameIds) { await this.findClient.clearSelection(tabId, frameId); } - for (let framePos = 0; framePos < frameIds.length; ++framePos) { - const found = await this.findClient.findNext( - tabId, - frameIds[framePos], - keyword - ); + for (const frameId of frameIds) { + const found = await this.findClient.findNext(tabId, frameId, keyword); if (found) { - await this.findRepository.setLocalState(tabId, { - frameIds, - framePos, - keyword, - }); + await this.findRepository.setLocalState(tabId, { frameId, keyword }); await this.consoleClient.showInfo(tabId, "Pattern found: " + keyword); return; } diff --git a/src/background/operators/impls/FindPrevOperator.ts b/src/background/operators/impls/FindPrevOperator.ts index 3c4411d..f8506b9 100644 --- a/src/background/operators/impls/FindPrevOperator.ts +++ b/src/background/operators/impls/FindPrevOperator.ts @@ -21,71 +21,65 @@ export default class FindPrevOperator implements Operator { return; } + let frameIds = await this.frameRepository.getFrameIds(tabId); + if (typeof frameIds === "undefined") { + // No frames are ready + return; + } + frameIds = frameIds.slice(0).reverse(); + const state = await this.findRepository.getLocalState(tabId); if (state) { - // Start to find the keyword from the current frame which last found on, - // and concat it to end of frame ids to perform a wrap-search - // - // ,- keyword should be in this frame - // | - // [100, 101, 0, 100] - // | - // `- continue from frame id 100 - // - const targetFrameIds = state.frameIds - .slice(state.framePos) - .concat( - state.frameIds.slice(0, state.framePos), - state.frameIds[state.framePos] - ); + const framePos = frameIds.indexOf(state.frameId); + if (framePos !== -1) { + // Start to find the keyword from the current frame which last found on, + // and concat it to end of frame ids to perform a wrap-search + // + // ,- keyword should be in this frame + // | + // [100, 101, 0, 100] + // | + // `- continue from frame id 100 + // + const targetFrameIds = frameIds + .slice(framePos) + .concat(frameIds.slice(0, framePos), frameIds[framePos]); - for (let i = targetFrameIds.length - 1; i >= 0; --i) { - const found = await this.findClient.findPrev( + for (const frameId of targetFrameIds) { + const found = await this.findClient.findPrev( + tabId, + frameId, + state.keyword + ); + if (found) { + this.findRepository.setLocalState(tabId, { + keyword: state.keyword, + frameId, + }); + return; + } + this.findClient.clearSelection(tabId, frameId); + } + + // The keyword is gone. + this.consoleClient.showError( tabId, - targetFrameIds[i], - state.keyword + "Pattern not found: " + state.keyword ); - if (found) { - this.findRepository.setLocalState(tabId, { - ...state, - framePos: (i + state.framePos) % state.frameIds.length, // save current frame position or first - }); - return; - } - this.findClient.clearSelection(tabId, targetFrameIds[i]); + return; } - - // The keyword is gone. - this.consoleClient.showError( - tabId, - "Pattern not found: " + state.keyword - ); - return; } const keyword = await this.findRepository.getGlobalKeyword(); if (keyword) { - const frameIds = await this.frameRepository.getFrameIds(tabId); - if (typeof frameIds === "undefined") { - // No frames are ready - return; - } for (const frameId of frameIds) { await this.findClient.clearSelection(tabId, frameId); } - for (let framePos = frameIds.length - 1; framePos >= 0; --framePos) { - const found = await this.findClient.findPrev( - tabId, - frameIds[framePos], - keyword - ); + for (const frameId of frameIds) { + const found = await this.findClient.findPrev(tabId, frameId, keyword); if (found) { - await this.findRepository.setLocalState(tabId, { - frameIds, - framePos, - keyword, - }); + await this.findRepository.setLocalState(tabId, { frameId, keyword }); await this.consoleClient.showInfo(tabId, "Pattern found: " + keyword); return; } diff --git a/src/background/repositories/FindRepository.ts b/src/background/repositories/FindRepository.ts index 46ee390..3492759 100644 --- a/src/background/repositories/FindRepository.ts +++ b/src/background/repositories/FindRepository.ts @@ -6,8 +6,7 @@ const FIND_LOCAL_KEYWORD_KEY = "find-local-keyword"; export type FindState = { keyword: string; - framePos: number; - frameIds: number[]; + frameId: number; }; export default interface FindRepository { diff --git a/src/background/repositories/ReadyFrameRepository.ts b/src/background/repositories/ReadyFrameRepository.ts index 725f604..72ae5a4 100644 --- a/src/background/repositories/ReadyFrameRepository.ts +++ b/src/background/repositories/ReadyFrameRepository.ts @@ -7,7 +7,9 @@ type State = { [tabId: number]: number[] }; export default interface ReadyFrameRepository { clearFrameIds(tabId: number): Promise; - addFrameId(tabId: number, fraemId: number): Promise; + addFrameId(tabId: number, frameId: number): Promise; + + removeFrameId(tabId: number, frameId: number): Promise; getFrameIds(tabId: number): Promise; } @@ -29,12 +31,26 @@ export class ReadyFrameRepositoryImpl implements ReadyFrameRepository { return Promise.resolve(); } - addFrameId(tabId: number, fraemId: number): Promise { + addFrameId(tabId: number, frameId: number): Promise { let state: State | undefined = this.cache.get(REPOSITORY_KEY); if (typeof state === "undefined") { state = {}; } - state[tabId] = (state[tabId] || []).concat(fraemId); + state[tabId] = (state[tabId] || []).concat(frameId); + this.cache.set(REPOSITORY_KEY, state); + return Promise.resolve(); + } + + removeFrameId(tabId: number, frameId: number): Promise { + const state: State | undefined = this.cache.get(REPOSITORY_KEY); + if (typeof state === "undefined") { + return Promise.resolve(); + } + const ids = state[tabId]; + if (typeof ids === "undefined") { + return Promise.resolve(); + } + state[tabId] = ids.filter((id) => id != frameId); this.cache.set(REPOSITORY_KEY, state); return Promise.resolve(); } diff --git a/src/background/usecases/StartFindUseCase.ts b/src/background/usecases/StartFindUseCase.ts index a62462f..6aad962 100644 --- a/src/background/usecases/StartFindUseCase.ts +++ b/src/background/usecases/StartFindUseCase.ts @@ -40,16 +40,11 @@ export default class StartFindUseCase { await this.findClient.clearSelection(tabId, frameId); } - for (let framePos = 0; framePos < frameIds.length; ++framePos) { - const found = await this.findClient.findNext( - tabId, - frameIds[framePos], - keyword - ); + for (const frameId of frameIds) { + const found = await this.findClient.findNext(tabId, frameId, keyword); if (found) { await this.findRepository.setLocalState(tabId, { - frameIds, - framePos, + frameId, keyword, }); await this.consoleClient.showInfo(tabId, "Pattern found: " + keyword); diff --git a/src/content/Application.ts b/src/content/Application.ts index a12c3c6..6b881fe 100644 --- a/src/content/Application.ts +++ b/src/content/Application.ts @@ -41,7 +41,21 @@ export default class Application { if (window.self === window.top) { this.routeMasterComponents(); } - return this.routeCommonComponents(); + this.routeCommonComponents(); + // Make sure the background script sends a message to the content script by + // establishing a connection. If the background script tries to send a + // message to a frame on which cannot run the content script, it fails with + // a message "Could not establish connection." + // + // The port is never used, and the messages are delivered via + // `browser.tabs.sendMessage` API because sending a message via port cannot + // receive returned value. + // + // /* on background script */ + // port.sendMessage({ type: "do something" }); <- returns void + // + browser.runtime.connect(undefined, { name: "vimvixen-find" }); + return Promise.resolve(); } private routeMasterComponents() { diff --git a/test/background/mock/MockReadyFrameRepository.ts b/test/background/mock/MockReadyFrameRepository.ts index 63b7cf4..a95b2e1 100644 --- a/test/background/mock/MockReadyFrameRepository.ts +++ b/test/background/mock/MockReadyFrameRepository.ts @@ -9,6 +9,10 @@ export default class MockReadyFrameRepository implements ReadyFrameRepository { throw new Error("not implemented"); } + removeFrameId(_tabId: number, _frameId: number): Promise { + throw new Error("not implemented"); + } + getFrameIds(_tabId: number): Promise { throw new Error("not implemented"); } diff --git a/test/background/operators/impls/FindNextOperator.test.ts b/test/background/operators/impls/FindNextOperator.test.ts index b5088df..7509ef4 100644 --- a/test/background/operators/impls/FindNextOperator.test.ts +++ b/test/background/operators/impls/FindNextOperator.test.ts @@ -32,6 +32,10 @@ describe("FindNextOperator", () => { active: true, }); currentTabId = currentTab.id!; + + sinon + .stub(frameRepository, "getFrameIds") + .returns(Promise.resolve(frameIds)); }); describe("#run", () => { @@ -54,8 +58,7 @@ describe("FindNextOperator", () => { sinon.stub(findRepository, "getLocalState").returns( Promise.resolve({ keyword, - frameIds, - framePos: 1, + frameId: 100, }) ); @@ -68,7 +71,7 @@ describe("FindNextOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 1 }); + .withArgs(currentTabId, { keyword, frameId: 100 }); await sut.run(); @@ -80,8 +83,7 @@ describe("FindNextOperator", () => { sinon.stub(findRepository, "getLocalState").returns( Promise.resolve({ keyword, - frameIds, - framePos: 1, + frameId: 100, }) ); @@ -102,7 +104,7 @@ describe("FindNextOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 2 }); + .withArgs(currentTabId, { keyword, frameId: 101 }); await sut.run(); @@ -114,8 +116,7 @@ describe("FindNextOperator", () => { sinon.stub(findRepository, "getLocalState").returns( Promise.resolve({ keyword, - frameIds, - framePos: 2, + frameId: 101, }) ); @@ -136,7 +137,7 @@ describe("FindNextOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 0 }); + .withArgs(currentTabId, { keyword, frameId: 0 }); await sut.run(); @@ -151,9 +152,6 @@ describe("FindNextOperator", () => { sinon .stub(findRepository, "getGlobalKeyword") .returns(Promise.resolve(keyword)); - sinon - .stub(frameRepository, "getFrameIds") - .returns(Promise.resolve(frameIds)); sinon.stub(consoleClient, "showInfo").returns(Promise.resolve()); const mockFindClient = sinon.mock(findClient); @@ -168,7 +166,7 @@ describe("FindNextOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 0 }); + .withArgs(currentTabId, { keyword, frameId: 0 }); await sut.run(); diff --git a/test/background/operators/impls/FindPrevOperator.test.ts b/test/background/operators/impls/FindPrevOperator.test.ts index 296f0dd..090f815 100644 --- a/test/background/operators/impls/FindPrevOperator.test.ts +++ b/test/background/operators/impls/FindPrevOperator.test.ts @@ -32,6 +32,10 @@ describe("FindPrevOperator", () => { active: true, }); currentTabId = currentTab.id!; + + sinon + .stub(frameRepository, "getFrameIds") + .returns(Promise.resolve(frameIds.slice(0))); }); describe("#run", () => { @@ -54,8 +58,7 @@ describe("FindPrevOperator", () => { sinon.stub(findRepository, "getLocalState").returns( Promise.resolve({ keyword, - frameIds, - framePos: 1, + frameId: 100, }) ); @@ -68,7 +71,7 @@ describe("FindPrevOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 1 }); + .withArgs(currentTabId, { keyword, frameId: 100 }); await sut.run(); @@ -80,8 +83,7 @@ describe("FindPrevOperator", () => { sinon.stub(findRepository, "getLocalState").returns( Promise.resolve({ keyword, - frameIds, - framePos: 1, + frameId: 100, }) ); @@ -102,7 +104,7 @@ describe("FindPrevOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 0 }); + .withArgs(currentTabId, { keyword, frameId: 0 }); await sut.run(); @@ -114,8 +116,7 @@ describe("FindPrevOperator", () => { sinon.stub(findRepository, "getLocalState").returns( Promise.resolve({ keyword, - frameIds, - framePos: 0, + frameId: 0, }) ); @@ -136,7 +137,7 @@ describe("FindPrevOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 2 }); + .withArgs(currentTabId, { keyword, frameId: 101 }); await sut.run(); @@ -151,9 +152,6 @@ describe("FindPrevOperator", () => { sinon .stub(findRepository, "getGlobalKeyword") .returns(Promise.resolve(keyword)); - sinon - .stub(frameRepository, "getFrameIds") - .returns(Promise.resolve(frameIds)); sinon.stub(consoleClient, "showInfo").returns(Promise.resolve()); const mockFindClient = sinon.mock(findClient); @@ -168,7 +166,7 @@ describe("FindPrevOperator", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { keyword, frameIds, framePos: 2 }); + .withArgs(currentTabId, { keyword, frameId: 101 }); await sut.run(); diff --git a/test/background/repositories/FindRepository.test.ts b/test/background/repositories/FindRepository.test.ts index a08dc6d..d8c9506 100644 --- a/test/background/repositories/FindRepository.test.ts +++ b/test/background/repositories/FindRepository.test.ts @@ -25,12 +25,12 @@ describe("background/repositories/FindRepositoryImpl", () => { await sut.setLocalState(10, { keyword: "Hello, world", - frameIds: [20, 21], - framePos: 0, + frameId: 11, }); const state = await sut.getLocalState(10); expect(state?.keyword).to.equal("Hello, world"); + expect(state?.frameId).to.equal(11); expect(await sut.getLocalState(20)).to.be.undefined; }); diff --git a/test/background/usecases/StartFindUseCase.test.ts b/test/background/usecases/StartFindUseCase.test.ts index 99ab508..24e1fdc 100644 --- a/test/background/usecases/StartFindUseCase.test.ts +++ b/test/background/usecases/StartFindUseCase.test.ts @@ -46,7 +46,7 @@ describe("StartFindUseCase", () => { const mockFindRepository = sinon.mock(findRepository); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { frameIds, framePos: 1, keyword }); + .withArgs(currentTabId, { keyword, frameId: 100 }); const mockConsoleClient = sinon.mock(consoleClient); mockConsoleClient .expects("showInfo") @@ -76,10 +76,10 @@ describe("StartFindUseCase", () => { mockFindRepository .expects("getLocalState") .withArgs(currentTabId) - .returns(Promise.resolve({ keyword, frameIds, framePos: 0 })); + .returns(Promise.resolve({ keyword, frameId: 0 })); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { frameIds, framePos: 1, keyword }); + .withArgs(currentTabId, { keyword, frameId: 100 }); const mockConsoleClient = sinon.mock(consoleClient); mockConsoleClient .expects("showInfo") @@ -115,7 +115,7 @@ describe("StartFindUseCase", () => { .returns(Promise.resolve(keyword)); mockFindRepository .expects("setLocalState") - .withArgs(currentTabId, { frameIds, framePos: 1, keyword }); + .withArgs(currentTabId, { keyword, frameId: 100 }); const mockConsoleClient = sinon.mock(consoleClient); mockConsoleClient .expects("showInfo") -- cgit v1.2.3