-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Centralize error message and make it display it more prominently
- Create a central EditorError component and use in graphical and form - Remove message coming from GLSP server and replace with UI extension - Ensure tool palette minimize button is shown depending on state Fixes #65
- Loading branch information
1 parent
5bd00ad
commit 0b6b02a
Showing
20 changed files
with
485 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
156 changes: 156 additions & 0 deletions
156
e2e-tests/src/page-objects/crossmodel-composite-editor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2024 CrossBreeze. | ||
********************************************************************************/ | ||
|
||
import { ElementHandle, Page } from '@playwright/test'; | ||
import { isElementVisible, normalizeId, OSUtil, TheiaApp, TheiaEditor, TheiaTextEditor, urlEncodePath } from '@theia/playwright'; | ||
import { TheiaMonacoEditor } from '@theia/playwright/lib/theia-monaco-editor'; | ||
import { join } from 'path'; | ||
|
||
export type CompositeEditorName = 'Code Editor' | 'Form Editor' | 'System Diagram' | 'Mapping Diagram'; | ||
|
||
export class CrossModelCompositeEditor extends TheiaEditor { | ||
constructor( | ||
protected filePath: string, | ||
app: TheiaApp | ||
) { | ||
// shell-tab-code-editor-opener:file:///c%3A/Users/user/AppData/Local/Temp/cloud-ws-JBUhb6/sample.txt:1 | ||
// code-editor-opener:file:///c%3A/Users/user/AppData/Local/Temp/cloud-ws-JBUhb6/sample.txt:1 | ||
super( | ||
{ | ||
tabSelector: normalizeId( | ||
`#shell-tab-cm-composite-editor-handler:file://${urlEncodePath( | ||
join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath) | ||
)}` | ||
), | ||
viewSelector: normalizeId( | ||
`#cm-composite-editor-handler:file://${urlEncodePath(join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath))}` | ||
) | ||
}, | ||
app | ||
); | ||
} | ||
|
||
protected editorTabSelector(editor: CompositeEditorName): string { | ||
return this.viewSelector + ` div.p-TabBar-tabLabel:has-text("${editor}")`; | ||
} | ||
|
||
protected isEditorTabVisible(editor: CompositeEditorName): Promise<boolean> { | ||
return isElementVisible(this.editorTabElement(editor)); | ||
} | ||
|
||
protected editorTabElement(editor: CompositeEditorName): Promise<ElementHandle<SVGElement | HTMLElement> | null> { | ||
return this.page.$(this.editorTabSelector(editor)); | ||
} | ||
|
||
async switchToEditor(editor: CompositeEditorName): Promise<ElementHandle<SVGElement | HTMLElement>> { | ||
const selector = this.editorTabSelector(editor); | ||
const tab = await this.page.waitForSelector(selector, { state: 'visible' }); | ||
await tab?.click(); | ||
return tab; | ||
} | ||
|
||
async switchToCodeEditor(): Promise<IntegratedCodeEditor> { | ||
await this.switchToEditor('Code Editor'); | ||
const textEditor = new IntegratedCodeEditor(this.filePath, this.app, this.editorTabSelector('Code Editor')); | ||
await textEditor.waitForVisible(); | ||
return textEditor; | ||
} | ||
|
||
async switchToFormEditor(): Promise<IntegratedFormEditor> { | ||
await this.switchToEditor('Form Editor'); | ||
const formEditor = new IntegratedFormEditor(this.filePath, this.app, this.editorTabSelector('Form Editor')); | ||
await formEditor.waitForVisible(); | ||
return formEditor; | ||
} | ||
|
||
async switchToSystemDiagram(): Promise<IntegratedSystemDiagramEditor> { | ||
await this.switchToEditor('System Diagram'); | ||
const diagramEditor = new IntegratedSystemDiagramEditor(this.filePath, this.app, this.editorTabSelector('System Diagram')); | ||
await diagramEditor.waitForVisible(); | ||
return diagramEditor; | ||
} | ||
|
||
async switchToMappingDiagram(): Promise<IntegratedMappingDiagramEditor> { | ||
await this.switchToEditor('Mapping Diagram'); | ||
const diagramEditor = new IntegratedMappingDiagramEditor(this.filePath, this.app, this.editorTabSelector('Mapping Diagram')); | ||
await diagramEditor.waitForVisible(); | ||
return diagramEditor; | ||
} | ||
} | ||
|
||
export class IntegratedCodeEditor extends TheiaTextEditor { | ||
constructor(filePath: string, app: TheiaApp, tabSelector: string) { | ||
// shell-tab-code-editor-opener:file:///c%3A/Users/user/AppData/Local/Temp/cloud-ws-JBUhb6/sample.txt:1 | ||
// code-editor-opener:file:///c%3A/Users/user/AppData/Local/Temp/cloud-ws-JBUhb6/sample.txt:1 | ||
super(filePath, app); | ||
this.data.viewSelector = normalizeId( | ||
`#code-editor-opener:file://${urlEncodePath(join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath))}` | ||
); | ||
this.data.tabSelector = tabSelector; | ||
this.monacoEditor = new TheiaMonacoEditor(this.viewSelector, app); | ||
} | ||
} | ||
|
||
export class IntegratedFormEditor extends TheiaEditor { | ||
constructor(filePath: string, app: TheiaApp, tabSelector: string) { | ||
super( | ||
{ | ||
tabSelector, | ||
viewSelector: normalizeId( | ||
`#form-editor-opener:file://${urlEncodePath(join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath))}` | ||
) | ||
}, | ||
app | ||
); | ||
} | ||
|
||
async hasError(errorMessage: string): Promise<boolean> { | ||
return hasViewError(this.page, this.viewSelector, errorMessage); | ||
} | ||
} | ||
|
||
export class IntegratedSystemDiagramEditor extends TheiaEditor { | ||
constructor(filePath: string, app: TheiaApp, tabSelector: string) { | ||
super( | ||
{ | ||
tabSelector, | ||
viewSelector: normalizeId( | ||
`#system-diagram:file://${urlEncodePath(join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath))}` | ||
) | ||
}, | ||
app | ||
); | ||
} | ||
|
||
async hasError(errorMessage: string): Promise<boolean> { | ||
return hasViewError(this.page, this.viewSelector, errorMessage); | ||
} | ||
} | ||
|
||
export class IntegratedMappingDiagramEditor extends TheiaEditor { | ||
constructor(filePath: string, app: TheiaApp, tabSelector: string) { | ||
super( | ||
{ | ||
tabSelector, | ||
viewSelector: normalizeId( | ||
`#mapping-diagram:file://${urlEncodePath(join(app.workspace.escapedPath, OSUtil.fileSeparator, filePath))}` | ||
) | ||
}, | ||
app | ||
); | ||
} | ||
|
||
async hasError(errorMessage: string): Promise<boolean> { | ||
return hasViewError(this.page, this.viewSelector, errorMessage); | ||
} | ||
} | ||
|
||
export async function hasViewError(page: Page, viewSelector: string, message: string): Promise<boolean> { | ||
const visible = await isElementVisible(page.$(viewSelector)); | ||
if (!visible) { | ||
return false; | ||
} | ||
await page.waitForSelector(viewSelector + ' .editor-diagnostics-error-message:has-text("' + message + '")'); | ||
return true; | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2023 CrossBreeze. | ||
********************************************************************************/ | ||
import { expect } from '@playwright/test'; | ||
import test, { app } from '../fixtures/crossmodel-fixture'; | ||
import { CrossModelCompositeEditor } from '../page-objects/crossmodel-composite-editor'; | ||
|
||
test.describe('CrossModel Error Views', () => { | ||
test('Form Editor should show error if model code is broken', async () => { | ||
const editor = await app.openEditor('example-entity.entity.cm', CrossModelCompositeEditor); | ||
expect(editor).toBeDefined(); | ||
|
||
const codeEditor = await editor.switchToCodeEditor(); | ||
expect(codeEditor).toBeDefined(); | ||
await codeEditor.addTextToNewLineAfterLineByLineNumber(2, 'break-model'); | ||
|
||
const formEditor = await editor.switchToFormEditor(); | ||
expect( | ||
await formEditor.hasError( | ||
// eslint-disable-next-line max-len | ||
"The file contains one or more errors. Please fix the error(s) using the 'Code Editor'. This perspective will be read-only until the errors are resolved." | ||
) | ||
).toBeTruthy(); | ||
}); | ||
|
||
test('System Diagram Editor should show error if model code is broken', async () => { | ||
const editor = await app.openEditor('example-diagram.diagram.cm', CrossModelCompositeEditor); | ||
expect(editor).toBeDefined(); | ||
|
||
const codeEditor = await editor.switchToCodeEditor(); | ||
expect(codeEditor).toBeDefined(); | ||
await codeEditor.addTextToNewLineAfterLineByLineNumber(2, 'break-model'); | ||
|
||
const diagramEditor = await editor.switchToSystemDiagram(); | ||
expect( | ||
await diagramEditor.hasError( | ||
// eslint-disable-next-line max-len | ||
"The file contains one or more errors. Please fix the error(s) using the 'Code Editor'. This perspective will be read-only until the errors are resolved." | ||
) | ||
).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.