mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
feat: support setting temporary config from URL
This commit is contained in:
parent
c88b817d60
commit
69cd8d71a7
13 changed files with 68 additions and 15 deletions
|
|
@ -1,8 +1,9 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import { getTextContent, sleep } from '../../utils'
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() => page.goto('https://github.com/GitakoExtension/test-empty'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com/GitakoExtension/test-empty`))
|
||||
|
||||
it('should render error message', async () => {
|
||||
await sleep(5000)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import { expectToFind, expectToNotFind, sleep, waitForRedirect } from '../../utils'
|
||||
|
||||
jest.retryTimes(3)
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/commits/develop'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com/EnixCoda/Gitako/commits/develop`))
|
||||
|
||||
it('should not break go back in history', async () => {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import { expectToFind, expectToNotFind, sleep, waitForRedirect } from '../../utils'
|
||||
|
||||
jest.retryTimes(3)
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/tree/develop/src'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com/EnixCoda/Gitako/tree/develop/src`))
|
||||
|
||||
it('should not break go back in history', async () => {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import {
|
||||
collapseFloatModeSidebar,
|
||||
expandFloatModeSidebar,
|
||||
|
|
@ -11,7 +12,7 @@ import {
|
|||
jest.retryTimes(3)
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/tree/develop/src'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com/EnixCoda/Gitako/tree/develop/src`))
|
||||
|
||||
it('should work with PJAX', async () => {
|
||||
await sleep(3000)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import {
|
||||
expandFloatModeSidebar,
|
||||
expectToFind,
|
||||
|
|
@ -11,7 +12,7 @@ import {
|
|||
jest.retryTimes(3)
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/tree/test/multiple-changes'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com/EnixCoda/Gitako/tree/test/multiple-changes`))
|
||||
|
||||
it('should work with PJAX', async () => {
|
||||
await sleep(3000)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import { expandFloatModeSidebar, expectToFind, expectToNotFind, scroll } from '../../utils'
|
||||
|
||||
jest.retryTimes(3)
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() =>
|
||||
page.goto('https://github.com/EnixCoda/Gitako/tree/test/200-changed-files-200-lines-each'),
|
||||
page.goto(
|
||||
testURL`https://github.com/EnixCoda/Gitako/tree/test/200-changed-files-200-lines-each`,
|
||||
),
|
||||
)
|
||||
|
||||
it('should render Gitako', async () => {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
* Confirm basic behaviors of puppeteer assertions
|
||||
*/
|
||||
|
||||
import { testURL } from '../../testURL'
|
||||
import { expectToFind, expectToNotFind } from '../../utils'
|
||||
|
||||
describe(`in random page`, () => {
|
||||
beforeAll(() => page.goto('https://google.com'))
|
||||
beforeAll(() => page.goto(testURL`https://google.com`))
|
||||
|
||||
it('wait for hidden non-exist element should resolve null', async () => {
|
||||
expect(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import { expectToFind, sleep, waitForRedirect } from '../../utils'
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/tree/develop/src'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com/EnixCoda/Gitako/tree/develop/src`))
|
||||
|
||||
it('expand to target on load and after redirect', async () => {
|
||||
await sleep(3000)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { testURL } from '../../testURL'
|
||||
import { expectToNotFind } from '../../utils'
|
||||
|
||||
describe(`in GitHub homepage`, () => {
|
||||
beforeAll(() => page.goto('https://github.com'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com`))
|
||||
|
||||
it('should not render Gitako', async () => {
|
||||
await expectToNotFind('.gitako-side-bar .gitako-side-bar-body-wrapper')
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { selectors } from '../../selectors'
|
||||
import { testURL } from '../../testURL'
|
||||
import { expectToFind } from '../../utils'
|
||||
|
||||
describe(`in Gitako project page`, () => {
|
||||
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/pull/71'))
|
||||
beforeAll(() => page.goto(testURL`https://github.com/EnixCoda/Gitako/pull/71`))
|
||||
|
||||
it('should render Gitako', async () => {
|
||||
await expectToFind(selectors.gitako.bodyWrapper)
|
||||
|
|
|
|||
11
__tests__/testURL.ts
Normal file
11
__tests__/testURL.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// string template function, take input URL string and add a search param
|
||||
// example: url`http://g.com` => `http://g.com?k1=v1`
|
||||
export function testURL(strings: TemplateStringsArray, ...values: unknown[]) {
|
||||
const raw = strings.reduce((acc, str, i) => acc + str + (values[i] ?? ''), '')
|
||||
const url = new URL(raw, 'http://localhost')
|
||||
url.searchParams.append(
|
||||
'gitako-config-accessToken',
|
||||
JSON.stringify(process.env.GITAKO_ACCESS_TOKEN ?? 'fallback_token'),
|
||||
)
|
||||
return url.href
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ export const getDefaultConfigs: () => Config = () => ({
|
|||
|
||||
const configKeyArray = Object.values(configKeys)
|
||||
|
||||
function applyDefaultConfigs(configs: Partial<Config>) {
|
||||
function applyDefaultConfigs(configs: Partial<Config> = {}) {
|
||||
const defaultConfigs = getDefaultConfigs()
|
||||
return configKeyArray.reduce((applied, key) => {
|
||||
Object.assign(applied, { [key]: key in configs ? configs[key] : defaultConfigs[key] })
|
||||
|
|
@ -94,15 +94,45 @@ const updateConfigRef = async (config: Partial<Config>) => {
|
|||
const configMigration = migrateConfig()
|
||||
configMigration.then(async () => updateConfigRef(await get()))
|
||||
|
||||
let loadedConfigFromURL = false
|
||||
|
||||
function getConfigFromURL() {
|
||||
const config: Partial<Config> = {}
|
||||
// config params pattern:
|
||||
// ?gitako-config-<key>=<json-value>
|
||||
new URLSearchParams(window.location.search).forEach((value, key) => {
|
||||
if (key.match(/^gitako-config-/)) {
|
||||
const configKey = key.replace(/^gitako-config-/, '')
|
||||
if (configKey in configKeys) {
|
||||
try {
|
||||
config[configKeys[configKey as configKeys]] = JSON.parse(value)
|
||||
loadedConfigFromURL = true
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to parse config "${configKey}" from URL: ${value}`, {
|
||||
cause: error,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.warn(`Unknown config "${configKey}" from URL: ${value}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
async function get(): Promise<Config> {
|
||||
await configMigration
|
||||
const config = await storageHelper.get<Record<string, Config>>([platformStorageKey])
|
||||
return applyDefaultConfigs(config?.[platformStorageKey] || {})
|
||||
const savedConfig = (await storageHelper.get<Record<string, Config>>([platformStorageKey]))?.[
|
||||
platformStorageKey
|
||||
]
|
||||
const configFromURL = getConfigFromURL()
|
||||
return applyDefaultConfigs({ ...savedConfig, ...configFromURL })
|
||||
}
|
||||
|
||||
async function set(config: Config) {
|
||||
updateConfigRef(config)
|
||||
return await storageHelper.set({ [platformStorageKey]: config })
|
||||
if (!loadedConfigFromURL) await storageHelper.set({ [platformStorageKey]: config })
|
||||
}
|
||||
|
||||
export const configHelper = { get, set }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"target": "ESNext",
|
||||
"jsx": "react",
|
||||
"strict": true,
|
||||
"lib": ["dom", "es2017.object", "es2016", "ES2019.Array", "ES2020.String"],
|
||||
"lib": ["dom", "es2017.object", "es2016", "ES2019.Array", "ES2020.String", "ES2022.Error"],
|
||||
"baseUrl": "src",
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue