Skip to content

Commit

Permalink
fix: resolve e2e test failures (#2122)
Browse files Browse the repository at this point in the history
* feat: resolve e2e test failures

* fix: re-add get-port

* chore: remove http-serve and update http-server

* test(fix): explore.page.js race condition

* fix: run e2e tests 10 times on CI to ensure no flakiness

* chore: move repeat-each to github CI

this ensures kubo interop CI test only runs them once.. we don't want the burden of flakiness on them

* test(chore): make remote-api.test.js test in serial for now

* test(fix): remote-api.test.js

* test(ci): allow multiple workers in CI

* Revert "test(ci): allow multiple workers in CI"

This reverts commit ad43e04.

* test(CI): shard e2e playwright tests in CI
  • Loading branch information
SgtPooki committed Jun 14, 2023
1 parent eefde73 commit 106627d
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 90 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/test-e2e.yml
Expand Up @@ -9,7 +9,9 @@ jobs:
strategy:
fail-fast: false
matrix:
backend: [go] # TODO: add 'js' – see https://github.com/ipfs/ipfs-webui/issues/1737
backend: [go]
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
shardTotal: [10]
steps:
- uses: actions/checkout@v3.5.2

Expand Down Expand Up @@ -39,7 +41,7 @@ jobs:
run: npm run test:build

- name: Run E2E against ${{ matrix.backend }}-ipfs
run: E2E_IPFSD_TYPE=${{ matrix.backend }} npm run test:e2e
run: E2E_IPFSD_TYPE=${{ matrix.backend }} npm run test:e2e -- --repeat-each 10 --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} # run each test 10 times to ensure no flakiness

- name: Generate nyc coverage report
id: coverage
Expand Down
192 changes: 127 additions & 65 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -176,9 +176,9 @@
"esm": "^3.2.25",
"fake-indexeddb": "^3.1.8",
"get-port": "^5.1.1",
"go-ipfs": "^0.18.1",
"go-ipfs": "^0.20.0",
"http-proxy": "^1.18.1",
"http-server": "^0.12.3",
"http-server": "^14.1.1",
"ipfs": "0.58.3",
"ipfs-core-utils": "^0.18.0",
"ipfsd-ctl": "^12.2.2",
Expand Down
7 changes: 1 addition & 6 deletions test/e2e/explore.test.js
Expand Up @@ -46,12 +46,7 @@ async function testExploredCid ({ cid, type, humanReadableCID, page, fillOutForm
await page.press('[data-id="FilesExploreForm"] button[title="Inspect"]', 'Enter')
}

// wait for loading
const spinner = page.locator('.la-ball-triangle-path')
await spinner.waitFor({ state: 'hidden' })

// expect node type
await page.waitForSelector(`"${cid}"`)
await page.waitForSelector(`.joyride-explorer-cid [title="${cid}"]`) // cid is displayed in the CID INFO section.
await page.waitForSelector(`[title="${type}"]`)

if (humanReadableCID != null) {
Expand Down
9 changes: 8 additions & 1 deletion test/e2e/ipns.test.js
Expand Up @@ -3,6 +3,9 @@ import { createController } from 'ipfsd-ctl'
import { path as getGoIpfsPath } from 'go-ipfs'
import * as kuboRpcModule from 'kubo-rpc-client'

// TODO: Fix parallelism of these tests
test.describe.configure({ mode: 'serial' })

test.describe('IPNS publishing', () => {
let ipfsd
let peeraddr
Expand Down Expand Up @@ -72,12 +75,16 @@ test.describe('IPNS publishing', () => {
let keyName
let ipfs
test.beforeEach(async ({ page }) => {
keyName = 'pet-name-e2e-ipns-test-' + new Date().getTime()
keyName = 'pet-name-e2e-ipns-test-' + new Date().getTime() + Math.random().toString(16).slice(2)
ipfs = kuboRpcModule.create(process.env.IPFS_RPC_ADDR)
await ipfs.key.gen(keyName)
await page.goto('/#/files')
await page.reload()
})
test.afterEach(async () => {
await ipfs.key.rm(keyName)
ipfs = null
})

const testFilename = 'ipns-test.txt'
const testCid = '/ipfs/bafyaaeqkcaeaeeqknfyg44znorsxg5akdafa'
Expand Down
8 changes: 4 additions & 4 deletions test/e2e/playwright.config.js
Expand Up @@ -19,7 +19,6 @@ const config = {
viewport: { width: 1366, height: 768 },
baseURL: `http://localhost:${webuiPort}/`,
storageState: 'test/e2e/state.json',
// actionTimeout: 30* 1000,
trace: 'on-first-retry'
},
/* TODO: test against other engines?
Expand Down Expand Up @@ -50,14 +49,15 @@ const config = {
webServer: [
{
command: `node ipfs-backend.js ${rpcPort}`,
url: `http://127.0.0.1:${rpcPort}/webui`, // we don't use webui bundled with daemon, but it is a good test of when its http server is fully booted
timeout: 5 * 1000,
port: rpcPort,
cwd: './setup',
reuseExistingServer: !process.env.CI
},
{
// command: 'npm run start',
command: `npx http-server ./build/ -c-1 -a 127.0.0.1 -p ${webuiPort}`,
port: webuiPort,
timeout: 5 * 1000,
url: `http://localhost:${webuiPort}/`,
cwd: '../../',
reuseExistingServer: !process.env.CI,
env: {
Expand Down
8 changes: 4 additions & 4 deletions test/e2e/remote-api.test.js
Expand Up @@ -115,11 +115,11 @@ test.describe('Remote API tests', () => {
}

const switchIpfsApiEndpointViaSettings = async (endpoint, page) => {
await page.click('a[href="#/settings"]')
await page.click('[role="menubar"] a[href="#/settings"]')
const selector = 'input[id="api-address"]'
await page.waitForSelector(selector)
await page.fill(selector, endpoint)
await page.press(selector, 'Enter')
const locator = await page.locator(selector)
await locator.fill(endpoint)
await locator.press('Enter')
await waitForIpfsApiEndpoint(endpoint, page)
}

Expand Down
27 changes: 27 additions & 0 deletions test/e2e/setup/global-setup.js
Expand Up @@ -6,13 +6,40 @@ import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// make sure that ipfs-backend is fully running
const ensureKuboDaemon = async (apiOpts) => {
const backendEndpoint = `${apiOpts.protocol}://${apiOpts.host}:${apiOpts.port}`
const body = new FormData()
body.append('file', new Blob(new Uint8Array([1, 2, 3])), 'test.txt')

const fakeFileResult = await fetch(`${backendEndpoint}/api/v0/block/put`, {
body,
method: 'POST'
})
if (!fakeFileResult.ok) {
console.error('fakeFileResult not okay', await fakeFileResult.text())
throw new Error(`IPFS backend not running at ${backendEndpoint}`)
}

const { Key: cidString } = await fakeFileResult.json()
const getContentResult = await fetch(`${backendEndpoint}/api/v0/block/get?arg=${cidString}`, {
method: 'POST'
})
if (!getContentResult.ok) {
console.error('Could not get fake file', await getContentResult.text())
throw new Error(`IPFS backend not running at ${backendEndpoint}`)
}
}

const globalSetup = async config => {
// Read and expose backend info in env availables inside of test() blocks
const { rpcAddr, id, agentVersion, apiOpts } = JSON.parse(fs.readFileSync(path.join(__dirname, 'ipfs-backend.json')))
process.env.IPFS_RPC_ADDR = rpcAddr
process.env.IPFS_RPC_ID = id
process.env.IPFS_RPC_VERSION = agentVersion

await ensureKuboDaemon(apiOpts)

// Set and save RPC API endpoint in storageState, so test start against
// desired endpoint
const { baseURL, storageState } = config.projects[0].use
Expand Down

0 comments on commit 106627d

Please sign in to comment.