Skip to content

Commit

Permalink
feat: enable (optional) autosave of the changes. Minor ui and layout …
Browse files Browse the repository at this point in the history
…adaptations.

tests: fix failing unit and integration tests
  • Loading branch information
dmijatovic committed Apr 25, 2024
1 parent 7af06d8 commit e64b922
Show file tree
Hide file tree
Showing 30 changed files with 627 additions and 196 deletions.
31 changes: 19 additions & 12 deletions apps/haddock3-download/integration-tests/dupheader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test.describe('given an uploaded archive with a workflow.cfg file with a duplica
molecules = [
'some.pdb'
]
[caprieval]
[caprieval]
Expand All @@ -23,30 +23,37 @@ test.describe('given an uploaded archive with a workflow.cfg file with a duplica
// Upload workflow archive
await page.locator('text="Upload" >> input[type="file"]')
.setInputFiles({ name: 'workflow.zip', mimeType: 'application/zip', buffer: archive.toBuffer() })
})

// Click text=Text
await page.locator('text=Text').click()

test('it should show uplaoded file', async ({ page }) => {
// Click Files tab
await page.locator('text=Files').click()
// validate file button is present
await page.waitForSelector('button:has-text("some.pdb")')
})

test('should have both headers and added index number', async ({ page }) => {
// Click Text tab
await page.locator('text=Text').click()
// debug
// await page.pause()

const highlightedCode = await page.locator('#highlightedcode pre')
const lines = await highlightedCode.allTextContents()
const content = lines.join('\n')
const expected = dedent`
run_dir = 'run1'
molecules = [
'some.pdb',
]
molecules = [
'some.pdb',
]
[caprieval]
run_dir = 'run1'
[caprieval]
['caprieval.2']
['caprieval.2']
`
`
expect(content).toEqual(expected)

Check failure on line 57 in apps/haddock3-download/integration-tests/dupheader.spec.ts

View workflow job for this annotation

GitHub Actions / build

[chromium] › dupheader.spec.ts:35:3 › given an uploaded archive with a workflow.cfg file with a duplicated header › should have both headers and added index number

1) [chromium] › dupheader.spec.ts:35:3 › given an uploaded archive with a workflow.cfg file with a duplicated header › should have both headers and added index number Error: expect(received).toEqual(expected) // deep equality - Expected - 8 + Received + 2 ↵ molecules = [ - 'some.pdb', - ] - - run_dir = 'run1' - - [caprieval] - - ['caprieval.2'] + ] + ↵ 55 | 56 | ` > 57 | expect(content).toEqual(expected) | ^ 58 | }) 59 | }) 60 | at /home/runner/work/workflow-builder/workflow-builder/apps/haddock3-download/integration-tests/dupheader.spec.ts:57:21
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ import { test, expect } from '@playwright/test'
test('Verify that [object Object] bug does not show up (issue #74)', async ({ page }) => {
await page.goto('http://localhost:3000')

// debugger
// await page.pause()

// Load the example
await page.locator('text=docking-protein-ligand').click()

// Click 'text' and ensure the files appear
await page.locator('text=Text').click()
// validate that file is used
await page.locator('text=Files').click()
await page.waitForSelector('button:has-text("data/target.pdb")')

// change to 'text' tab
await page.locator('text=Text').click()

// verify that the [object Object] text does not show up
// see https://github.com/i-VRESSE/workflow-builder/issues/74
const highlightedCode = await page.locator('#highlightedcode pre')
Expand Down
30 changes: 21 additions & 9 deletions apps/haddock3-download/integration-tests/topoaamol.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,38 @@ import { readFile } from 'fs/promises'
test.describe('given 1 molecule and a topoaa node', () => {
test.beforeEach(async ({ page }) => {
await page.goto('http://localhost:3000')

// Disable autosave
// await page.locator('text=Autosave').click();

// Click input[type="text"]
await page.locator('input[type="text"]').click()
// Fill input[type="text"]
await page.locator('input[type="text"]').fill('x')
// Upload e2a-hpr_1GGR.pdb
const file1 = await readFile('./integration-tests/data/e2a-hpr_1GGR.pdb')

// Click text=Input MoleculesThe input molecules that will be used for docking. >> button
await page.locator('text=Input MoleculesThe input molecules that will be used for docking. >> button').click()
await page.locator('text=1* >> input[type="file"]')
.setInputFiles({ name: 'e2a-hpr_1GGR.pdb', mimeType: 'chemical/x-pdb', buffer: file1 })
// Click text=Save
await page.locator('button:has-text("Save")').click()
// Click text=Cancel
await page.locator('button:has-text("Cancel")').click()
// Click button:has-text("topoaa")

// add topoaa step to workflow
await page.locator('button:has-text("topoaa")').click()
// select topoaa step
await page.locator('button:has-text("1. topoaa")').click()

// Click #expander4molecule svg
await page.locator('#expander4molecule svg').click()
// Click #expander4input_molecules svg
await page.locator('#expander4input_molecules svg').click()
// Click text=Save
await page.locator('button:has-text("Save")').click()
// Click text=Text
await page.locator('text=Text').click()
// await page.locator('button:has-text("Save")').click()
})

test('should have "[topoaa.mol1]" header', async ({ page }) => {
// select Text tab
await page.locator('text=Text').click()
await expectHighlightedCodeToContain(page, '[topoaa.mol1]')
})

Expand All @@ -41,7 +47,7 @@ test.describe('given 1 molecule and a topoaa node', () => {
// It is important to call waitForEvent before click to set up waiting.
page.waitForEvent('download'),
// Triggers the download.
page.locator('text=Download archive').click()
page.locator('text=Download').click()
])
// wait for download to complete
path = await download.path() ?? ''
Expand All @@ -64,10 +70,16 @@ test.describe('given 1 molecule and a topoaa node', () => {
await page.locator('text="Upload" >> input[type="file"]')
.setInputFiles({ name: 'workflow.zip', mimeType: 'application/zip', buffer: file1 })

// ensure file is uploaded
await page.locator('text=Files').click()
await page.waitForSelector('button:has-text("e2a-hpr_1GGR.pdb")')
})

test('should have "[topoaa.mol1]" header', async ({ page }) => {
// debugger
// await page.pause()
// change to Text tab
await page.locator('text=Text').click()
await expectHighlightedCodeToContain(page, '[topoaa.mol1]')
})
})
Expand Down
3 changes: 2 additions & 1 deletion apps/haddock3-download/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
grid-template-areas: "head head head"
"catalog workflow node"
"catalog workflow-actions node-actions";
grid-template-columns: min-content minmax(12rem,1fr) minmax(20rem,2fr);
grid-template-columns: min-content minmax(19rem,1fr) minmax(20rem,2fr);
grid-template-rows: auto 1fr auto;
column-gap: 1rem;
}
Expand Down Expand Up @@ -91,6 +91,7 @@ div[role="button"],
display: flex;
gap: 1rem;
padding: 1rem 0rem;
align-items: baseline;
}

/* Show panel section is clickable */
Expand Down
90 changes: 64 additions & 26 deletions apps/haddock3-download/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,78 @@ import {
WorkflowDownloadButton,
WorkflowPanel,
WorkflowUploadButton,
Wrapper
Wrapper,
useAutosaveValue,
useSetAutosave
} from '@i-vresse/wb-core'

import '@i-vresse/wb-form/dist/index.css'
import './App.css'

function App (): JSX.Element {
function AutosaveManagement (): JSX.Element {
const autosave = useAutosaveValue()
const setAutosave = useSetAutosave()

return (
<Wrapper>
<div className='page'>
<GridArea area='head'>
<Header />
</GridArea>
<GridArea area='catalog'>
<CatalogPanel>
<CatalogPicker />
</CatalogPanel>
</GridArea>
<GridArea area='workflow' className='workflow-area'>
<WorkflowPanel>
<WorkflowUploadButton />
</WorkflowPanel>
</GridArea>
<GridArea area='node'>
<NodePanel />
</GridArea>
<GridArea className='action-row' area='workflow-actions'>
<div
className='form-group form-check'
>
<input
type='checkbox'
className='form-check-input'
id='autosave'
checked={autosave}
onChange={(e) => {
setAutosave(!autosave)
}}
/>
<label
className='form-check-label'
htmlFor='autosave'
>
Autosave
</label>
</div>
)
}

function PageContent (): JSX.Element {
const autosave = useAutosaveValue()
console.group('PageContent')
console.log('autosave...', autosave)
console.groupEnd()

return (
<div className='page'>
<GridArea area='head'>
<Header />
</GridArea>
<GridArea area='catalog'>
<CatalogPanel>
<CatalogPicker />
</CatalogPanel>
</GridArea>
<GridArea area='workflow' className='workflow-area'>
<WorkflowPanel>
<WorkflowDownloadButton />
<WorkflowUploadButton />
<WorkflowClear />
</GridArea>
<GridArea className='action-row' area='node-actions'>
<FormActions />
</GridArea>
</div>
<AutosaveManagement />
</WorkflowPanel>
</GridArea>
<GridArea area='node'>
<NodePanel />
{/* show form actions if autosave is OFF */}
{!autosave ? <FormActions /> : null}
</GridArea>
</div>
)
}

function App (): JSX.Element {
return (
<Wrapper>
<PageContent />
</Wrapper>
)
}
Expand Down
11 changes: 5 additions & 6 deletions packages/core/src/CatalogCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ export const CatalogCategory = ({ name, description, collapsed: initiallyCollaps
const style = {
// TODO On https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type
// disclosure-open/closed are said to be experimental, find how much compatibility there is.
listStyleType: collapsed ? 'disclosure-closed' : 'disclosure-open'
listStyleType: collapsed ? 'disclosure-closed' : 'disclosure-open',
cursor: 'pointer'
// utf failed in chrome
// listStyleType: collapsed ? '⏷' : '⏵'
}
return (
<li
style={style} onClick={(e) => {
if (e.target === e.currentTarget) {
// only toggle when list marker is clicked
return setCollapsed((c) => !c)
}
style={style}
onClick={(e) => {
setCollapsed((c) => !c)
}}
>
<span title={description}>{name}</span>
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/CatalogNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ export const CatalogNode = ({ id, label }: ICatalogNode): JSX.Element => {
{...attributes}
title={label}
className='btn btn-light btn-sm btn-catalog-node'
onClick={() => addNodeToWorkflow(id)}
onClick={(e) => {
// prevent bubbling click even to parent which toggles the group
e.stopPropagation()
// add node to workflow
addNodeToWorkflow(id)
}}
>
<span>{id}</span>
<div
Expand Down
19 changes: 17 additions & 2 deletions packages/core/src/FilesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,31 @@ import { useFiles } from './store'

export const FilesList = (): JSX.Element => {
const files = useFiles()
const fileList = Object.keys(files)

function downloadFile (filename: string): void {
saveAs(files[filename], filename)
}

if (fileList?.length === 0) {
return (
<div style={{
padding: '0.5rem'
}}
>
<h5>No files to show</h5>
</div>
)
}

return (
<div>
<div style={{
padding: '0.5rem'
}}
>
<h5>Files</h5>
<ul>
{Object.keys(files).map(filename =>
{fileList.map(filename =>
<li key={filename}><button className='btn btn-link' onClick={() => downloadFile(filename)}>{filename}</button></li>
)}
</ul>
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/FormActions.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export const NothingSelected: ComponentStory<typeof FormActions> = () => {

export const GlobalParametersSelected: ComponentStory<typeof FormActions> =
() => {
const { toggleGlobalEdit } = useWorkflow()
const { setEditingGlobal } = useWorkflow()
const submitFormRefSetter = useSetActiveSubmitButton()
useEffect(toggleGlobalEdit, [])
useEffect(() => setEditingGlobal(true), [])
return (
<>
<button ref={submitFormRefSetter} style={{ display: 'none' }} />
Expand Down
16 changes: 4 additions & 12 deletions packages/core/src/FormActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,15 @@ import { useSelectNodeIndex, useActiveSubmitButton, useWorkflow } from './store'
* )
* ```
* The FormActions component will use `submitFormRefSetter` to submit form.
*
* For example to render the actions when global parameter editing is selected do
*
* ```js
* import { useWorkflow } from '@i-vresse/wb-core/dist/store'
*
* const { toggleGlobalEdit } = useWorkflow()
* toggleGlobalEdit()
* ```
*/
export const FormActions = (): JSX.Element => {
export const FormActions = (): JSX.Element|null => {
const index = useSelectNodeIndex()
const { deleteNode, clearNodeSelection } = useWorkflow()
const submitFormRef = useActiveSubmitButton()
const { editingGlobal, toggleGlobalEdit } = useWorkflow()
const { editingGlobal, setEditingGlobal } = useWorkflow()
if (submitFormRef === undefined || !(index > -1 || editingGlobal)) {
return <></>
return null
}
const DeleteButton = (
<button
Expand All @@ -62,7 +54,7 @@ export const FormActions = (): JSX.Element => {
</button>
<button
className='btn btn-light'
onClick={() => editingGlobal ? toggleGlobalEdit() : clearNodeSelection()}
onClick={() => editingGlobal ? setEditingGlobal(false) : clearNodeSelection()}
title='Forget changes made in form'
>
Cancel
Expand Down
Loading

0 comments on commit e64b922

Please sign in to comment.