Skip to content

Commit

Permalink
fix: e2e/explore.test.js succeeds in offline mode (#2109)
Browse files Browse the repository at this point in the history
* test(e2e-explore): add apollo block fixtures

* test(e2e-explore): remove children fixtures

* test(e2e-explore): add project apollo archive test

* test(e2e-explore): use fixtures for XKCD archives

* chore: self-PR review issues

* Update .gitattributes

Co-authored-by: Marcin Rataj <lidel@lidel.org>

* Update test/e2e/explore.test.js

Co-authored-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>

---------

Co-authored-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
Co-authored-by: Marcin Rataj <lidel@lidel.org>
  • Loading branch information
3 people committed Mar 22, 2023
1 parent f2bf41b commit a5e9ac6
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 63 deletions.
4 changes: 4 additions & 0 deletions .gitattributes
@@ -1 +1,5 @@
* text=auto
test/e2e/fixtures/explore/blocks/README.md text
test/e2e/fixtures/**/Qm* binary linguist-generated
test/e2e/fixtures/**/*.raw binary linguist-generated
test/e2e/fixtures/**/*.car binary linguist-generated
184 changes: 121 additions & 63 deletions test/e2e/explore.test.js
@@ -1,12 +1,15 @@
import { test, expect } from './setup/coverage.js'
import { readFile } from 'fs/promises'
import { readFileSync } from 'fs'
import { join, dirname } from 'path'
import * as kuboRpcModule from 'kubo-rpc-client'
import { fileURLToPath } from 'url'

import { create } from 'kubo-rpc-client'
import { CID } from 'multiformats/cid'
import * as dagPb from '@ipld/dag-pb'
import { sha256 } from 'multiformats/hashes/sha2'

import { test, expect } from './setup/coverage.js'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

Expand Down Expand Up @@ -59,6 +62,29 @@ async function testExploredCid ({ cid, type, humanReadableCID, page, fillOutForm
}
}

/**
* Loads saved block fixtures from fixtures/explore/blocks and adds them locally to the ipfs node
* @param {object} param0
* @param {import('kubo-rpc-client').IPFSHTTPClient} param0.ipfs
* @param {string|string[]} param0.blockCid
* @param {object} param0.blockPutArgs
*/
async function loadBlockFixtures ({ ipfs, blockCid, blockPutArgs = { format: 'v0' } }) {
try {
if (Array.isArray(blockCid)) {
return await Promise.all(blockCid.map(cid => loadBlockFixtures({ ipfs, blockCid: cid, blockPutArgs })))
}
// read the data from the file
const data = await readFile(join(__dirname, '/fixtures/explore/blocks', blockCid), { encoding: '' })
// add the data to the ipfs node
const result = await ipfs.block.put(data, blockPutArgs)
// check that the CID returned from block.put matches the given block fixture CID
expect(result.toString()).toBe(blockCid)
} catch (e) {
console.error(e)
}
}

test.describe('Explore screen', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/#/explore')
Expand All @@ -74,11 +100,18 @@ test.describe('Explore screen', () => {
})

test.describe('Inspecting CID', () => {
/**
* @type {ReturnType<import('kubo-rpc-client')['create']>}
*/
let ipfs
test.beforeEach(async ({ page }) => {
ipfs = create(process.env.IPFS_RPC_ADDR)
})

test('should open raw CID', async ({ page }) => {
// add a local file to repo so test is fast and works in offline mode
const cid = 'bafkreicgkmwhdunxgdqwqveecdo3wqmgulb4azm6sfnrtvd7g47mnrixji'
const expectedData = readFileSync(join(__dirname, '../../LICENSE'), 'utf8')
const ipfs = kuboRpcModule.create(process.env.IPFS_RPC_ADDR)
const result = await ipfs.add(expectedData, { cidVersion: 1 })
await expect(result.cid.toString()).toStrictEqual(cid)

Expand All @@ -88,13 +121,9 @@ test.describe('Explore screen', () => {
type: 'raw',
humanReadableCID: 'base32 - cidv1 - raw - sha2-256~256~46532C71D1B730E168548410DDBB4186A2C3C0659E915B19D47F373EC6C5174A'
})

// should not have children, but this confirms that `traverseChildren` works fine when there are no children
await traverseChildren({ page, type: 'raw' })
})

test('should open dag-pb', async ({ page }) => {
const ipfs = kuboRpcModule.create(process.env.IPFS_RPC_ADDR)
const cidData = new Uint8Array(Buffer.from('hello world'))
const dagPbAsDagJson = {
Data: cidData,
Expand Down Expand Up @@ -122,11 +151,9 @@ test.describe('Explore screen', () => {
humanReadableCID: 'base32 - cidv1 - dag-pb - sha2-256~256~543AA6F6B9A533C8BF80568090CDF24B693AAA2F9B574A33784D8462FDC5579C',
type: 'dag-pb'
})
await traverseChildren({ page, type: 'dag-pb' })
})

test('should open dag-cbor cid', async ({ page }) => {
const ipfs = kuboRpcModule.create(process.env.IPFS_RPC_ADDR)
const type = 'dag-cbor'
const cidData = new Uint8Array(Buffer.from('hello world'))
const dagCborAsDagJson = {
Expand All @@ -146,78 +173,109 @@ test.describe('Explore screen', () => {
humanReadableCID: 'base32 - cidv1 - dag-cbor - sha2-256~256~497BC2F17946B7E5DE05715EB348E47F2A6ABE6CF34ECAE9F46E236BC6E49FF5',
type
})
await traverseChildren({ page, type: 'dag-cbor' })
})

test('should open dag-pb unixFS XKCD Archives', async ({ page }) => {
await loadBlockFixtures({
ipfs,
blockCid: [
'QmdmQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7RgQm',
'QmbQDovX7wRe9ek7u6QXe9zgCXkTzoUSsTFJEkrYV1HrVR',
'QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6'
]
})

await testExploredCid({
page,
cid: 'QmdmQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7RgQm',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~E536C7F88D731F374DCCB568AFF6F56E838A19382E488039B1CA8AD2599E82FE',
type: 'dag-pb'
})
await page.waitForSelector('"UnixFS"')
const firstChild = await page.waitForSelector('"1 - Barrel - Part 1"')
await firstChild.click()

await (await page.waitForSelector('"QmbQDovX7wRe9ek7u6QXe9zgCXkTzoUSsTFJEkrYV1HrVR"')).click()
await testExploredCid({
fillOutForm: false,
page,
cid: 'QmbQDovX7wRe9ek7u6QXe9zgCXkTzoUSsTFJEkrYV1HrVR',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~C212195DE60CE9B899EFDB2830101B16556018A24C7428E32198FAAB9D493F94',
type: 'dag-pb'
})
await page.waitForSelector('"UnixFS"')
await traverseChildren({ page, type: 'dag-pb' })

await (await page.waitForSelector('"QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6"')).click()
await testExploredCid({
fillOutForm: false,
page,
cid: 'QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~BB413C3DE0BA745523A3D701D6CB4283BCA7E187EC21556F4456036F692A5075',
type: 'dag-pb'
})
})
})
})

/**
* Click the first child of the currently inspected CID and repeat until there are no more children
* @param {object} param0
* @param {import('playwright').Page} param0.page
* @param {string} param0.type
*
* @returns {Promise<void>}
*/
async function traverseChildren ({ page, type }) {
let hasChildren = await clickFirstExploreChild({ page, type })
while (hasChildren) {
hasChildren = await clickFirstExploreChild({ page, type })
}
}
test('should explore Project Apollo Archive', async ({ page }) => {
await loadBlockFixtures({
ipfs,
blockCid: [
'QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D',
'QmeQtZfwuq6aWRarY9P3L9MWhZ6QTonDe9ahWECGBZjyEJ',
'QmVmf9vLEdWeBjh74kTibHVkim6iLsRXs5jhHzbSdWjoLt',
'QmT4hPa6EeeCaTAb4a6ddFf4Lk5da9C1f4nMBmMJgbAW3z',
'QmZA6h4vP17Ktw5vyMdSQNTvzsncQKDSifYwJznY461rY2',
'QmR2pm6hPxv7pEgNaPE477rVBNSZnbUgXsSn2R9RqK9tAH'
]
})

/**
* Click the first child of the currently inspected CID if it has children
*
* - [role="rowgroup"] - table of the content, not including header
* - [role="row"] - each row in the table (includes headers. need to filter out by prefixing parent rowgroup selector)
* - [role="gridcell"] - each cell in a row
*
* @param {object} param0
* @param {import('playwright').Page} param0.page
* @param {string} param0.type
* @returns {Promise<boolean>} true if a child was found and clicked
*/
async function clickFirstExploreChild ({ page, type }) {
// selector for the first content row's third column cell
const firstCidCell = page.locator('[role="rowgroup"] [role="row"]:nth-child(1) [role="gridcell"]:nth-child(3)')
if (await firstCidCell.isVisible()) {
// get the text content (the CID) of the cell
const cid = await firstCidCell.textContent()

await firstCidCell.click()
await firstCidCell.waitFor({ state: 'detached' })
await testExploredCid({
fillOutForm: false,
page,
cid,
humanReadableCID: null,
type
})
await testExploredCid({
page,
cid: 'QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~422896A1CE82A7B1CC0BA27C7D8DE2886C7DF95588473D5E88A28A9FCFA0E43E',
type: 'dag-pb'
})

return true
}
// no children found, return false so we can stop clicking through children.
return false
}
await (await page.waitForSelector('"QmeQtZfwuq6aWRarY9P3L9MWhZ6QTonDe9ahWECGBZjyEJ"')).click()
await testExploredCid({
page,
cid: 'QmeQtZfwuq6aWRarY9P3L9MWhZ6QTonDe9ahWECGBZjyEJ',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~EED0FABF56CC4483BD066183A55EDC7817D3549C394C1967521B35AAC9D51FF3',
type: 'dag-pb',
fillOutForm: false
})

await (await page.waitForSelector('"QmVmf9vLEdWeBjh74kTibHVkim6iLsRXs5jhHzbSdWjoLt"')).click()
await testExploredCid({
page,
cid: 'QmVmf9vLEdWeBjh74kTibHVkim6iLsRXs5jhHzbSdWjoLt',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~6E69D4FA6F373B9DAC05974C31CAE53A8F39A0C67A6895CAC1DD2B274C079B19',
type: 'dag-pb',
fillOutForm: false
})

await (await page.waitForSelector('"QmT4hPa6EeeCaTAb4a6ddFf4Lk5da9C1f4nMBmMJgbAW3z"')).click()
await testExploredCid({
page,
cid: 'QmT4hPa6EeeCaTAb4a6ddFf4Lk5da9C1f4nMBmMJgbAW3z',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~46342C25ED0D9CA0BCB2350DB258941A08BDFC0064E824FE39FBEB2171D604E9',
type: 'dag-pb',
fillOutForm: false
})

await (await page.waitForSelector('"QmZA6h4vP17Ktw5vyMdSQNTvzsncQKDSifYwJznY461rY2"')).click()
await testExploredCid({
page,
cid: 'QmZA6h4vP17Ktw5vyMdSQNTvzsncQKDSifYwJznY461rY2',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~A0BC8B9BA2A4F6A91311F259A648F259723F7C6E13061E42462FC15FE6E1CA5B',
type: 'dag-pb',
fillOutForm: false
})

await (await page.waitForSelector('"QmR2pm6hPxv7pEgNaPE477rVBNSZnbUgXsSn2R9RqK9tAH"')).click()
await testExploredCid({
page,
cid: 'QmR2pm6hPxv7pEgNaPE477rVBNSZnbUgXsSn2R9RqK9tAH',
humanReadableCID: 'base58btc - cidv0 - dag-pb - sha2-256~256~2801F8B9FF4924F0938CBAF0F53B43E68088DBE272C6905C8D7AAA21A67102A6',
type: 'dag-pb',
fillOutForm: false
})
})
})
})

0 comments on commit a5e9ac6

Please sign in to comment.