Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/e2e-testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
jobs:
test-e2e:
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
Expand Down
18 changes: 18 additions & 0 deletions test/e2e/helpers/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import type { Workbench } from 'wdio-vscode-service'
import { Key } from 'webdriverio'

export async function clearInput(input: WebdriverIO.Element) {
// Focus the input, sometimes clicking doesn't work
await input.setValue('')
await browser.keys([Key.Ctrl, 'a'])
await browser.keys(Key.Backspace)
}

/**
* Opens the Radicle view container in the sidebar, by clicking the radicle button in the
Expand All @@ -13,3 +21,13 @@ export async function openRadicleViewContainer(workbench: Workbench) {

await radicleViewControl?.openView()
}

export async function closeRadicleViewContainer(workbench: Workbench) {
const activityBar = workbench.getActivityBar()
await activityBar.wait()

const radicleViewControl = await activityBar.getViewControl('Radicle')
await radicleViewControl?.wait()

await radicleViewControl?.closeView()
}
22 changes: 21 additions & 1 deletion test/e2e/helpers/assertions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
import { browser } from '@wdio/globals'
import type { Workbench } from 'wdio-vscode-service'
import type { OutputView, Workbench } from 'wdio-vscode-service'

/**
* Asserts the Output Panel contains the expected text.
*/
export async function expectOutputToContain(outputView: OutputView, expected: string) {
await browser.waitUntil(
async () => {
/**
* The text in the Output Panel is split by newlines, which can be affected by the size
* of the window. To avoid this, we join the text into a single string.
*/
const joinedText = (await outputView.getText()).join('')

return joinedText.includes(expected)
},
{
timeoutMsg: `expected the output text to contain "${expected}"`,
},
)
}

/**
* Asserts that the CLI Commands and Patches sections are visible in the sidebar. This is
Expand Down
6 changes: 5 additions & 1 deletion test/e2e/specs/onboarding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { $, cd } from 'zx'
import type * as VsCode from 'vscode'
import isEqual from 'lodash/isEqual'
import { expectStandardSidebarViewsToBeVisible } from '../helpers/assertions'
import { openRadicleViewContainer } from '../helpers/actions'
import { closeRadicleViewContainer, openRadicleViewContainer } from '../helpers/actions'
import { getFirstWelcomeViewText } from '../helpers/queries'
import { backupNodeHomePath, e2eTestDirPath, nodeHomePath } from '../constants/config'

Expand All @@ -16,6 +16,10 @@ describe('Onboarding Flow', () => {
workbench = await browser.getWorkbench()
})

after(async () => {
await closeRadicleViewContainer(workbench)
})

describe('VS Code, *before* Radicle is installed,', () => {
after(async () => {
await $`mv ${backupNodeHomePath} ${nodeHomePath}`
Expand Down
124 changes: 124 additions & 0 deletions test/e2e/specs/patch-details.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import type { WebView, Workbench } from 'wdio-vscode-service'
import { $, browser } from '@wdio/globals'
import { $ as zx } from 'zx'
import { Key } from 'webdriverio'
import { openRadicleViewContainer } from '../helpers/actions'

const selectors = {
openPatchDetailsButton: 'aria/Open Patch Details',
changePathStatusButton: '[title="Change Patch Status"]',
draftRadioButton: 'aria/Draft',
stopEditingPatchStatusButton: '[title="Stop Editing Patch Status"]',
refreshPatchDataButton: '[title="Refresh Patch Data"]',
editPatchTitleButton: '[title="Edit Patch Title and Description"]',
patchTitleInput: 'aria/Patch Title:',
patchDescriptionInput: 'aria/Patch Description:',
savePatchTitleButton: '[title="Save Changes to Radicle (Ctrl + Enter)"]',
openPatchIcon: '.codicon-git-pull-request',
draftPatchIcon: '.codicon-git-pull-request-draft',
closedPatchIcon: '.codicon-git-pull-request-closed',
}

/**
* These tests are failing because the extension is not picking up httpd.
* An iteration of this suite with adjustments to run locally (with a pre-existing patch) has been
* tested (on macOS) and works as expected.
* Barring any unexpected behavior due to the CI environment, these tests *should* pass once the
* httpd issue is resolved.
*
* TODO: Figure out why the extension is not picking up httpd
*/
describe.skip('Patch Details', () => {
const patchTitle = 'feat: foo bar'
let workbench: Workbench

before(async () => {
workbench = await browser.getWorkbench()
await zx`git checkout -b branch-1`
await zx`echo "Hello, World!" > hello.txt`
await zx`git add .`
await zx`git commit -m "${patchTitle}"`
await zx`git push rad HEAD:refs/patches`
await openRadicleViewContainer(workbench)
await openPatchDetails(workbench, patchTitle)
})

describe("VS Code, when viewing a patch's details,", () => {
it('allows the user to edit the patch status', async () => {
const patchDetails = await switchToFirstWebView(workbench)

await $(selectors.changePathStatusButton).click()
await $(selectors.draftRadioButton).click()
await $(selectors.stopEditingPatchStatusButton).click()
await $(selectors.refreshPatchDataButton).moveTo()

await expect($(`header ${selectors.draftPatchIcon}`)).toBeDisplayed()

await patchDetails?.close()

await expect(
await (await findPatch(workbench, patchTitle))?.elem.$(selectors.draftPatchIcon),
).toBeDisplayed()
})

it('allows the user to edit that patch title and description', async () => {
const patchDetails = await switchToFirstWebView(workbench)
await $(selectors.editPatchTitleButton).click()

const newTitle = 'feat: new foo bar'
const newDescription = 'foo bar baz'
await findAndFillInput(selectors.patchTitleInput, newTitle)
await findAndFillInput(selectors.patchDescriptionInput, newDescription)
await $(selectors.savePatchTitleButton).click()

await expect($(`p=${newTitle}`)).toBeDisplayed()

await expect($(`p=${newDescription}`)).toBeDisplayed()

await patchDetails?.close()

await expect(await findPatch(workbench, newTitle)).toBeDisplayed()
})
})
})

async function findAndFillInput(selector: string, value: string) {
await $(selector).click()
await browser.keys([Key.Ctrl, 'a'])
await browser.keys(value.split(''))
}

async function findPatch(workbench: Workbench, label: string) {
const sidebarView = workbench.getSideBar().getContent()
const patchesSection = await sidebarView.getSection('PATCHES')
const patch = await patchesSection.findItem(label)

return patch
}

async function openPatchDetails(workbench: Workbench, label: string) {
const patch = await findPatch(workbench, label)
if (!patch) {
return undefined
}

await patch.elem.moveTo()
await patch.elem.$(selectors.openPatchDetailsButton)?.click()

return patch
}

async function switchToFirstWebView(workbench: Workbench) {
let webviews: WebView[] = []
await browser.waitUntil(
async () => {
webviews = await workbench.getAllWebviews()

return webviews.length > 0
},
{ timeoutMsg: 'no webviews found' },
)
await webviews[0]?.open()

return webviews[0]
}
Loading