feat: 新增包文件
This commit is contained in:
299
packages/electron-chrome-extensions/spec/chrome-tabs-spec.ts
Normal file
299
packages/electron-chrome-extensions/spec/chrome-tabs-spec.ts
Normal file
@@ -0,0 +1,299 @@
|
||||
import { expect } from 'chai'
|
||||
import { app, BrowserWindow } from 'electron'
|
||||
import { emittedOnce } from './events-helpers'
|
||||
|
||||
import { useExtensionBrowser, useServer } from './hooks'
|
||||
import { ChromeExtensionImpl } from '../dist/types/browser/impl'
|
||||
|
||||
describe('chrome.tabs', () => {
|
||||
let assignTabDetails: ChromeExtensionImpl['assignTabDetails']
|
||||
|
||||
const server = useServer()
|
||||
const browser = useExtensionBrowser({
|
||||
url: server.getUrl,
|
||||
extensionName: 'rpc',
|
||||
assignTabDetails(details, tab) {
|
||||
assignTabDetails?.(details, tab)
|
||||
},
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
assignTabDetails = undefined
|
||||
})
|
||||
|
||||
describe('get()', () => {
|
||||
it('returns tab details', async () => {
|
||||
const tabId = browser.window.webContents.id
|
||||
const result = await browser.crx.exec('tabs.get', tabId)
|
||||
expect(result).to.be.an('object')
|
||||
expect(result.id).to.equal(tabId)
|
||||
expect(result.windowId).to.equal(browser.window.id)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getCurrent()', () => {
|
||||
it('gets details of the active tab', async () => {
|
||||
const result = await browser.crx.exec('tabs.getCurrent')
|
||||
expect(result).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
describe('create()', () => {
|
||||
it('creates a tab', async () => {
|
||||
const wcPromise = emittedOnce(app, 'web-contents-created')
|
||||
const tabInfo = await browser.crx.exec('tabs.create', { url: server.getUrl() })
|
||||
const [, wc] = await wcPromise
|
||||
expect(tabInfo).to.be.an('object')
|
||||
expect(tabInfo.id).to.equal(wc.id)
|
||||
expect(tabInfo.active).to.equal(true)
|
||||
expect(tabInfo.url).to.equal(server.getUrl())
|
||||
expect(tabInfo.windowId).to.equal(browser.window.id)
|
||||
expect(tabInfo.title).to.be.a('string')
|
||||
})
|
||||
|
||||
// TODO: Navigating to chrome-extension:// receives ERR_BLOCKED_BY_CLIENT (-20)
|
||||
it.skip('resolves relative URL', async () => {
|
||||
const relativeUrl = './options.html'
|
||||
const tabInfo = await browser.crx.exec('tabs.create', { url: relativeUrl })
|
||||
const url = new URL(relativeUrl, browser.extension.url).href
|
||||
expect(tabInfo).to.be.an('object')
|
||||
expect(tabInfo.url).to.equal(url)
|
||||
})
|
||||
|
||||
it('fails on chrome:// URLs', async () => {
|
||||
const tabInfo = await browser.crx.exec('tabs.create', { url: 'chrome://kill' })
|
||||
expect(tabInfo).to.be.a('null')
|
||||
})
|
||||
|
||||
it('fails on javascript: URLs', async () => {
|
||||
const tabInfo = browser.crx.exec('tabs.create', { url: "javascript:alert('hacked')" })
|
||||
expect(await tabInfo).to.be.a('null')
|
||||
})
|
||||
})
|
||||
|
||||
describe('query()', () => {
|
||||
it('gets the active tab', async () => {
|
||||
const result = await browser.crx.exec('tabs.query', { active: true })
|
||||
expect(result).to.be.an('array')
|
||||
expect(result).to.be.length(1)
|
||||
expect(result[0].id).to.be.equal(browser.window.webContents.id)
|
||||
expect(result[0].windowId).to.be.equal(browser.window.id)
|
||||
})
|
||||
|
||||
it('gets the active tab of multiple windows', async () => {
|
||||
const secondWindow = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
session: browser.session,
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
},
|
||||
})
|
||||
|
||||
browser.extensions.addTab(secondWindow.webContents, secondWindow)
|
||||
|
||||
const result = await browser.crx.exec('tabs.query', { active: true })
|
||||
expect(result).to.be.an('array')
|
||||
expect(result).to.be.length(2)
|
||||
expect(result[0].windowId).to.be.equal(browser.window.id)
|
||||
expect(result[1].windowId).to.be.equal(secondWindow.id)
|
||||
})
|
||||
|
||||
it('matches exact title', async () => {
|
||||
const results = await browser.crx.exec('tabs.query', { title: 'title' })
|
||||
expect(results).to.be.an('array')
|
||||
expect(results).to.be.length(1)
|
||||
expect(results[0].title).to.be.equal('title')
|
||||
})
|
||||
|
||||
it('matches title pattern', async () => {
|
||||
const results = await browser.crx.exec('tabs.query', { title: '*' })
|
||||
expect(results).to.be.an('array')
|
||||
expect(results).to.be.length(1)
|
||||
expect(results[0].title).to.be.equal('title')
|
||||
})
|
||||
|
||||
it('matches exact url', async () => {
|
||||
const url = server.getUrl()
|
||||
const results = await browser.crx.exec('tabs.query', { url })
|
||||
expect(results).to.be.an('array')
|
||||
expect(results).to.be.length(1)
|
||||
expect(results[0].url).to.be.equal(url)
|
||||
})
|
||||
|
||||
it('matches wildcard url pattern', async () => {
|
||||
const url = 'http://*/*'
|
||||
const results = await browser.crx.exec('tabs.query', { url })
|
||||
expect(results).to.be.an('array')
|
||||
expect(results).to.be.length(1)
|
||||
expect(results[0].url).to.be.equal(server.getUrl())
|
||||
})
|
||||
|
||||
it('matches either url pattern', async () => {
|
||||
const patterns = ['http://foo.bar/*', `${server.getUrl()}*`]
|
||||
const results = await browser.crx.exec('tabs.query', { url: patterns })
|
||||
expect(results).to.be.an('array')
|
||||
expect(results).to.be.length(1)
|
||||
expect(results[0].url).to.be.equal(server.getUrl())
|
||||
})
|
||||
})
|
||||
|
||||
describe('reload()', () => {
|
||||
it('reloads the active tab', async () => {
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.reload')
|
||||
await navigatePromise
|
||||
})
|
||||
|
||||
it('reloads a specified tab', async () => {
|
||||
const tabId = browser.window.webContents.id
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.reload', tabId)
|
||||
await navigatePromise
|
||||
})
|
||||
})
|
||||
|
||||
describe('update()', () => {
|
||||
it('navigates the tab', async () => {
|
||||
const tabId = browser.window.webContents.id
|
||||
const updateUrl = `${server.getUrl()}foo`
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.update', tabId, { url: updateUrl })
|
||||
await navigatePromise
|
||||
expect(browser.window.webContents.getURL()).to.equal(updateUrl)
|
||||
})
|
||||
|
||||
it('navigates the active tab', async () => {
|
||||
const updateUrl = `${server.getUrl()}foo`
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.update', { url: updateUrl })
|
||||
await navigatePromise
|
||||
expect(browser.window.webContents.getURL()).to.equal(updateUrl)
|
||||
})
|
||||
|
||||
it('fails on chrome:// URLs', async () => {
|
||||
const tabId = browser.webContents.id
|
||||
const tabInfo = await browser.crx.exec('tabs.update', tabId, { url: 'chrome://kill' })
|
||||
expect(tabInfo).to.be.a('null')
|
||||
})
|
||||
})
|
||||
|
||||
describe('goForward()', () => {
|
||||
it('navigates the active tab forward', async () => {
|
||||
const initialUrl = browser.window.webContents.getURL()
|
||||
const targetUrl = `${server.getUrl()}foo`
|
||||
await browser.window.webContents.loadURL(targetUrl)
|
||||
expect(browser.window.webContents.navigationHistory.canGoBack()).to.be.true
|
||||
browser.window.webContents.navigationHistory.goBack()
|
||||
await emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
expect(browser.window.webContents.navigationHistory.canGoForward()).to.be.true
|
||||
expect(browser.window.webContents.getURL()).to.equal(initialUrl)
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.goForward')
|
||||
await navigatePromise
|
||||
expect(browser.window.webContents.getURL()).to.equal(targetUrl)
|
||||
})
|
||||
|
||||
it('navigates a specified tab forward', async () => {
|
||||
const tabId = browser.window.webContents.id
|
||||
const initialUrl = browser.window.webContents.getURL()
|
||||
const targetUrl = `${server.getUrl()}foo`
|
||||
await browser.window.webContents.loadURL(targetUrl)
|
||||
expect(browser.window.webContents.navigationHistory.canGoBack()).to.be.true
|
||||
browser.window.webContents.navigationHistory.goBack()
|
||||
await emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
expect(browser.window.webContents.navigationHistory.canGoForward()).to.be.true
|
||||
expect(browser.window.webContents.getURL()).to.equal(initialUrl)
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.goForward', tabId)
|
||||
await navigatePromise
|
||||
expect(browser.window.webContents.getURL()).to.equal(targetUrl)
|
||||
})
|
||||
})
|
||||
|
||||
describe('goBack()', () => {
|
||||
it('navigates the active tab back', async () => {
|
||||
const initialUrl = browser.window.webContents.getURL()
|
||||
await browser.window.webContents.loadURL(`${server.getUrl()}foo`)
|
||||
expect(browser.window.webContents.navigationHistory.canGoBack()).to.be.true
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.goBack')
|
||||
await navigatePromise
|
||||
expect(browser.window.webContents.getURL()).to.equal(initialUrl)
|
||||
})
|
||||
|
||||
it('navigates a specified tab back', async () => {
|
||||
const tabId = browser.window.webContents.id
|
||||
const initialUrl = browser.window.webContents.getURL()
|
||||
await browser.window.webContents.loadURL(`${server.getUrl()}foo`)
|
||||
expect(browser.window.webContents.canGoBack()).to.be.true
|
||||
const navigatePromise = emittedOnce(browser.window.webContents, 'did-navigate')
|
||||
browser.crx.exec('tabs.goBack', tabId)
|
||||
await navigatePromise
|
||||
expect(browser.window.webContents.getURL()).to.equal(initialUrl)
|
||||
})
|
||||
})
|
||||
|
||||
describe('executeScript()', () => {
|
||||
it('injects code into a tab', async () => {
|
||||
const tabId = browser.window.webContents.id
|
||||
const [result] = await browser.crx.exec('tabs.executeScript', tabId, {
|
||||
code: 'location.href',
|
||||
})
|
||||
expect(result).to.equal(browser.window.webContents.getURL())
|
||||
})
|
||||
|
||||
it('injects code into the active tab', async () => {
|
||||
const [result] = await browser.crx.exec('tabs.executeScript', { code: 'location.href' })
|
||||
expect(result).to.equal(browser.window.webContents.getURL())
|
||||
})
|
||||
})
|
||||
|
||||
describe('onCreated', () => {
|
||||
it('emits when tab is added', async () => {
|
||||
const p = browser.crx.eventOnce('tabs.onCreated')
|
||||
|
||||
const secondWindow = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
session: browser.session,
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
},
|
||||
})
|
||||
const secondTab = secondWindow.webContents
|
||||
|
||||
const url = `${server.getUrl()}foo`
|
||||
await secondWindow.loadURL(url)
|
||||
|
||||
browser.extensions.addTab(secondTab, secondWindow)
|
||||
|
||||
const [tabDetails] = await p
|
||||
expect(tabDetails).to.be.an('object')
|
||||
expect(tabDetails.id).to.equal(secondTab.id)
|
||||
expect(tabDetails.windowId).to.equal(secondWindow.id)
|
||||
expect(tabDetails.url).to.equal(secondTab.getURL())
|
||||
})
|
||||
})
|
||||
|
||||
describe('onUpdated', () => {
|
||||
it('emits on "tab-updated" event', async () => {
|
||||
const p = browser.crx.eventOnce('tabs.onUpdated')
|
||||
|
||||
// Wait for tabs.onUpdated listener to be set
|
||||
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||
|
||||
assignTabDetails = (details) => {
|
||||
details.discarded = true
|
||||
}
|
||||
|
||||
browser.webContents.emit('tab-updated')
|
||||
|
||||
const [_tabId, changeInfo, _tabDetails] = await p
|
||||
expect(changeInfo).to.be.an('object')
|
||||
expect(Object.keys(changeInfo)).to.have.lengthOf(1)
|
||||
expect(changeInfo).to.haveOwnProperty('discarded')
|
||||
expect(changeInfo.discarded).to.equal(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user