Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui): fix file error + add colored support (#1108)
- Loading branch information
Showing
11 changed files
with
310 additions
and
23 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
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
42 changes: 42 additions & 0 deletions
42
packages/ui/client/components/views/ViewConsoleOutputEntry.cy.tsx
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 @@ | ||
import Filter from 'ansi-to-html' | ||
import ViewConsoleOutputEntry from './ViewConsoleOutputEntry.vue' | ||
|
||
const htmlSelector = '[data-type=html]' | ||
const textSelector = '[data-type=text]' | ||
|
||
describe('ViewConsoleOutputEntry', () => { | ||
it('test plain entry', () => { | ||
const content = new Date().toISOString() | ||
const container = cy.mount( | ||
<ViewConsoleOutputEntry | ||
task-name="test/text" | ||
type="stderr" | ||
time={Date.now()} | ||
html={false} | ||
content={content} | ||
/>, | ||
).get(textSelector) | ||
container.should('exist') | ||
container.invoke('text').then((t) => { | ||
expect(t, 'the message has the correct message').equals(content) | ||
}) | ||
}) | ||
it('test html entry', () => { | ||
const now = new Date().toISOString() | ||
const content = new Filter().toHtml(`\x1B[33m${now}\x1B[0m`) | ||
const container = cy.mount( | ||
<ViewConsoleOutputEntry | ||
task-name="test/html" | ||
type="stderr" | ||
time={Date.now()} | ||
html={true} | ||
content={content} | ||
/>, | ||
).get(htmlSelector) | ||
container.should('exist') | ||
container.children('span').then((c) => { | ||
expect(c, 'the message has the correct message').to.have.text(now) | ||
expect(c, 'the message has the correct text color').to.have.attr('style', 'color:#A50') | ||
}) | ||
}) | ||
}) |
28 changes: 28 additions & 0 deletions
28
packages/ui/client/components/views/ViewConsoleOutputEntry.vue
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,28 @@ | ||
<script setup lang="ts"> | ||
import type { UserConsoleLog } from '#types' | ||
const props = defineProps<{ | ||
taskName: string | ||
type: UserConsoleLog['type'] | ||
time: UserConsoleLog['time'] | ||
content: UserConsoleLog['content'] | ||
html: boolean | ||
}>() | ||
function formatTime(t: number) { | ||
return (new Date(t)).toLocaleTimeString() | ||
} | ||
</script> | ||
<template> | ||
<div border="b base" p-4> | ||
<div | ||
text-xs mb-1 | ||
:class="props.type === 'stderr' ? 'text-red-600 dark:text-red-300': 'op30'" | ||
> | ||
{{ formatTime(props.time) }} | {{ props.taskName }} | {{ props.type }} | ||
</div> | ||
<pre v-if="props.html" data-type="html" v-html="props.content" /> | ||
<pre v-else data-type="text" v-text="props.content" /> | ||
</div> | ||
</template> |
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,120 @@ | ||
import ViewReport from './ViewReport.vue' | ||
import type { File } from '#types' | ||
|
||
const taskErrorSelector = '.task-error' | ||
|
||
describe('ViewReport', () => { | ||
it('test plain stack trace', () => { | ||
const file: File = { | ||
id: 'f-1', | ||
name: 'test/plain-stack-trace.ts', | ||
type: 'suite', | ||
mode: 'run', | ||
filepath: 'test/plain-stack-trace.ts', | ||
result: { | ||
state: 'fail', | ||
error: { | ||
name: 'Do some test', | ||
stacks: [{ line: 10, column: 20, file: 'test/plain-stack-trace.ts', method: 'dummy test' }], | ||
message: 'Error: Transform failed with 1 error:', | ||
}, | ||
}, | ||
tasks: [], | ||
} | ||
const container = cy.mount(<ViewReport file={file} />) | ||
.get(taskErrorSelector) | ||
container.should('exist') | ||
container.children().then((c) => { | ||
c.get().forEach((e, idx) => { | ||
if (idx === 0) { | ||
expect(e.children[0].tagName, 'error contains <b> element').equals('B') | ||
expect(e.children[0].innerHTML, 'the <b> error element is correct').equals('Do some test') | ||
expect(e.innerText, 'error has the correct plain text').equals('Do some test: Error: Transform failed with 1 error:') | ||
} | ||
else { | ||
expect(e.children.length, 'the stack children elements is correct: stack and open in editor icon').equals(2) | ||
expect(e.children[0].innerHTML, 'stack has the correct message').equals(' - test/plain-stack-trace.ts:10:20') | ||
} | ||
}) | ||
}) | ||
}) | ||
it('test html stack trace without html message', () => { | ||
const file: File = { | ||
id: 'f-1', | ||
name: 'test/plain-stack-trace.ts', | ||
type: 'suite', | ||
mode: 'run', | ||
filepath: 'test/plain-stack-trace.ts', | ||
result: { | ||
state: 'fail', | ||
error: { | ||
name: 'Do some test', | ||
stack: '\x1B[33mtest/plain-stack-trace.ts\x1B[0m', | ||
message: 'Error: Transform failed with 1 error:', | ||
}, | ||
}, | ||
tasks: [], | ||
} | ||
const container = cy.mount(<ViewReport file={file} />) | ||
.get(taskErrorSelector) | ||
container.should('exist') | ||
container.children('pre').then((c) => { | ||
expect(c.text(), 'error has the correct plain text').equals('Do some test: Error: Transform failed with 1 error:test/plain-stack-trace.ts') | ||
const children = c.children().get() | ||
expect(children.length, 'the pre container has the correct children').equals(2) | ||
children.forEach((e, idx) => { | ||
if (idx === 0) { | ||
expect(e.tagName, 'error contains <b> element').equals('B') | ||
expect(e.innerHTML, 'the <b> error element is correct').equals('Do some test') | ||
} | ||
else { | ||
expect(e.children.length, 'the stack children elements is correct').equals(0) | ||
expect(e.innerHTML, 'stack has the correct message').equals('test/plain-stack-trace.ts') | ||
expect(e, 'the stack has the correct text color').to.have.attr('style', 'color:#A50') | ||
} | ||
}) | ||
}) | ||
}) | ||
it('test html stack trace and message', () => { | ||
const file: File = { | ||
id: 'f-1', | ||
name: 'test/plain-stack-trace.ts', | ||
type: 'suite', | ||
mode: 'run', | ||
filepath: 'test/plain-stack-trace.ts', | ||
result: { | ||
state: 'fail', | ||
error: { | ||
name: 'Do some test', | ||
stack: '\x1B[33mtest/plain-stack-trace.ts\x1B[0m', | ||
message: '\x1B[44mError: Transform failed with 1 error:\x1B[0m', | ||
}, | ||
}, | ||
tasks: [], | ||
} | ||
const container = cy.mount(<ViewReport file={file} />) | ||
.get(taskErrorSelector) | ||
container.should('exist') | ||
container.children('pre').then((c) => { | ||
expect(c.text(), 'error has the correct plain text').equals('Do some test: Error: Transform failed with 1 error:test/plain-stack-trace.ts') | ||
const children = c.children().get() | ||
expect(children.length, 'the pre container has the correct children').equals(3) | ||
children.forEach((e, idx) => { | ||
switch (idx) { | ||
case 0: | ||
expect(e.tagName, 'error contains <b> element').equals('B') | ||
expect(e.innerHTML, 'the <b> error element is correct').equals('Do some test') | ||
break | ||
case 1: | ||
expect(e.innerHTML, 'the error has the correct message').equals('Error: Transform failed with 1 error:') | ||
expect(e, 'the error has the correct background color').to.have.attr('style', 'background-color:#00A') | ||
break | ||
case 2: | ||
expect(e.children.length, 'the stack children elements is correct').equals(0) | ||
expect(e.innerHTML, 'stack has the correct message').equals('test/plain-stack-trace.ts') | ||
expect(e, 'the stack has the correct text color').to.have.attr('style', 'color:#A50') | ||
} | ||
}) | ||
}) | ||
}) | ||
}) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -211,3 +211,4 @@ html.dark { | |
.v-popper__popper .v-popper__arrow-outer { | ||
border-color: var(--background-color); | ||
} | ||
|
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.