Skip to content
Merged
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
73 changes: 44 additions & 29 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,93 +1,108 @@
# 1.1.1
# Change Log

All notable changes to the "@qavajs/html-formatter" will be documented in this file.

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

:rocket: - new feature
:beetle: - bugfix
:x: - deprecation/removal
:pencil: - chore
:microscope: - experimental

# [1.2.0]
- :rocket: added slideshow for screenshot attachments

# [1.1.1]
- fixed issue with required `showLogs`

# 1.1.0
# [1.1.0]
- added `showLogs` flag to enable/disable `text/x.cucumber.log+plain` logs

# 0.18.1
# [0.18.1]
- fixed home navigation

# 0.18.0
# [0.18.0]
- added capability to display http request and response
- updated main menu implementation

# 0.17.0
# [0.17.0]
- implemented runtime streaming

# 0.16.0
# [0.16.0]
- added dark theme

# 0.15.4
# [0.15.4]
- fixed multiple tags displaying

# 0.15.3
# [0.15.3]
- fixed logs overlay width

# 0.15.2
# [0.15.2]
- fixed duplicated scenarios in case of retries

# 0.15.1
# [0.15.1]
- fixed nano seconds conversion

# 0.15.0
# [0.15.0]
- migrated to react 18 and vite dev server
- added displaying of execution time for steps and scenarios
# 0.14.4

# [0.14.4]
- fixed [Feature that contains only undefined/skipped scenarios is displayed as passed](https://github.com/qavajs/html-formatter/issues/36)

# 0.14.3
# [0.14.3]
- fixed width and height of error and logs overlay

# 0.14.1
# [0.14.1]
- fixed stacktrace overlay
- fixed multiline and data table displaying

# 0.14.0
# [0.14.0]
- added support of named attachments

# 0.13.0
# [0.13.0]
- replaced legacy json formatter with custom one based on cucumber messages
- added support of named hooks

# 0.0.11
# [0.0.11]
- fixed $' replace issue

# 0.0.10
# [0.0.10]
- fixed issue of not escaped chars in logs

# 0.0.9
# [0.0.9]
- fixed issue of not opening features with /%# in names

# 0.0.8
# [0.0.8]
- added capability to attach cucumber logs

# 0.0.7
# [0.0.7]
- fixed duplicated results in case of same feature name

# 0.0.6
# [0.0.6]
- added unsupported attachment handler
- added multiple attachment support
- added mime type display for attachments
- added feature names to failed page
- added possibility to save state of "show only failed" switch

# 0.0.5
# [0.0.5]
- added capability to write tag name to clipboard
- added html attachments
- added capability to open attachment in new tab
- added capability to pass metadata
- added capability to pass metadata

# 0.0.4
# [0.0.4]
- added support application/json

# 0.0.3
# [0.0.3]
- fixed image fit
- fixed tags fit in title

# 0.0.2
# [0.0.2]
- added feature titles
- minor fixes

# 0.0.1
# [0.0.1]
- initial implementation
61 changes: 61 additions & 0 deletions formatter/index.html

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qavajs/html-formatter",
"version": "1.1.1",
"version": "1.2.0",
"main": "formatter/formatter.js",
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions src/components/AttachmentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const Attachment = (props: any) => {
}
if (json.includes(props.embedding.mime_type)) {
const pretty = JSON.stringify(JSON.parse(props.embedding.data), null, 2)
return <pre style={{width: '100vw'}}>{pretty}</pre>
return <pre style={{width: '100vw', color: 'whitesmoke'}}>{pretty}</pre>
}
if (iframe.includes(props.embedding.mime_type)) {
return <div style={{width: '90vw', height: '60vh'}}>
Expand All @@ -53,7 +53,7 @@ export const AttachmentModal = (modalProps: any) => {
<ModalWindow width={1200} style={{margin: 'auto'}}>
<Panel>
<ModalHeader title="Attachment" onClose={() => modalProps.success('close')}/>
<ScrollBars hasTopShadow hasBottomShadow>
<ScrollBars>
<FlexRow padding='24'>
<Attachment embedding={modalProps.embedding}/>
</FlexRow>
Expand Down
87 changes: 87 additions & 0 deletions src/components/SlideshowModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useState, useEffect, useCallback } from 'react';
import {
ModalBlocker,
ModalFooter,
ModalHeader,
ModalWindow,
FlexRow,
Panel,
ScrollBars,
LinkButton,
IconButton,
Text
} from '@epam/loveship';
import { openInNewTab } from '../utils/openInNewTab';

import PrevIcon from '@epam/assets/icons/common/navigation-chevron-left_left-24.svg?react';
import NextIcon from '@epam/assets/icons/common/navigation-chevron-right_right-24.svg?react';

export const SlideshowModal = (modalProps: any) => {
const { embeddings } = modalProps;
const [currentIndex, setCurrentIndex] = useState(0);
const current = embeddings[currentIndex];
const hasMultiple = embeddings.length > 1;

const goPrev = useCallback(() => {
setCurrentIndex(i => (i > 0 ? i - 1 : embeddings.length - 1));
}, [embeddings.length]);

const goNext = useCallback(() => {
setCurrentIndex(i => (i < embeddings.length - 1 ? i + 1 : 0));
}, [embeddings.length]);

useEffect(() => {
const handleKey = (e: KeyboardEvent) => {
if (e.key === 'ArrowLeft') goPrev();
if (e.key === 'ArrowRight') goNext();
};
window.addEventListener('keydown', handleKey);
return () => window.removeEventListener('keydown', handleKey);
}, [goPrev, goNext]);

return (
<ModalBlocker blockerShadow='dark' {...modalProps}>
<ModalWindow width={1200} style={{ margin: 'auto' }}>
<Panel>
<ModalHeader title='Screenshots' onClose={() => modalProps.success('close')} />
<ScrollBars>
<FlexRow padding='24' vPadding='12' alignItems='top'>
{hasMultiple && (
<div style={{ display: 'flex', alignItems: 'center', paddingTop: '8px' }}>
<IconButton icon={PrevIcon} onClick={goPrev} color='white' />
</div>
)}
<div style={{ flex: 1 }}>
<FlexRow>
<LinkButton
caption='Open in new tab'
size='30'
onClick={openInNewTab(current.data, current.mime_type)}
/>
</FlexRow>
<img
src={`data:${current.mime_type};base64,${current.data}`}
alt={current.fileName ?? `screenshot ${currentIndex + 1}`}
style={{ width: '100%' }}
/>
</div>
{hasMultiple && (
<div style={{ display: 'flex', alignItems: 'center', paddingTop: '8px' }}>
<IconButton icon={NextIcon} onClick={goNext} color='white' />
</div>
)}
</FlexRow>
{hasMultiple && (
<FlexRow padding='24' vPadding='12' justifyContent='center'>
<Text fontSize='14'>
{current.fileName ? `${current.fileName} — ` : ''}{currentIndex + 1} / {embeddings.length}
</Text>
</FlexRow>
)}
</ScrollBars>
<ModalFooter />
</Panel>
</ModalWindow>
</ModalBlocker>
);
};
16 changes: 14 additions & 2 deletions src/components/Step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import ResponseIcon from '@epam/assets/icons/common/content-code_braces-24.svg?r

import css from '../App.module.scss';
import { useUuiContext } from '@epam/uui-core';
import { supportedMimeTypes } from '../utils/supportedMimeTypes';
import { supportedMimeTypes, image } from '../utils/supportedMimeTypes';
import { openInNewTab } from '../utils/openInNewTab';
import { SlideshowModal } from './SlideshowModal';

const logPlainMimeType = 'text/x.cucumber.log+plain';
const responseMimeType = 'text/x.response.json';
Expand Down Expand Up @@ -71,6 +72,10 @@ const handleAttachmentClick = (embedding: any, svc: any) => {
return openInNewTab(embedding.data, embedding.mime_type)
}

const handleSlideshowClick = (embeddings: any[], svc: any) => {
return () => svc.uuiModals.show((props: any) => <SlideshowModal { ...props } embeddings={embeddings}/>)
}

const handleLogsClick = (logs: any[], svc: any) => {
return () => svc.uuiModals.show((props: any) => <LogsModal { ...props } logs={logs}/>)
}
Expand All @@ -83,7 +88,9 @@ export const Step = ({step}: {step: any}) => {
const svc = useUuiContext();
const logs = step.embeddings?.filter((embedding: any) => embedding.mime_type === logPlainMimeType) ?? [];
const responses = step.embeddings?.filter((embedding: any) => embedding.mime_type === responseMimeType) ?? [];
const attachments = step.embeddings?.filter((embedding: any) => ![logPlainMimeType, responseMimeType].includes(embedding.mime_type)) ?? [];
const allAttachments = step.embeddings?.filter((embedding: any) => ![logPlainMimeType, responseMimeType].includes(embedding.mime_type)) ?? [];
const screenshots = allAttachments.filter((embedding: any) => image.includes(embedding.mime_type));
const attachments = allAttachments.filter((embedding: any) => !image.includes(embedding.mime_type));
return <div>
<FlexRow>
{icon(step.result.status)}
Expand All @@ -106,6 +113,11 @@ export const Step = ({step}: {step: any}) => {
onClick={ handleResponseClick(embedding, svc) }
/>)
}
{screenshots.length > 0 && <LinkButton
icon={ AttachmentIcon }
caption={ screenshots.length > 1 ? `Screenshots (${screenshots.length})` : (screenshots[0].fileName ?? 'Screenshot') }
onClick={ handleSlideshowClick(screenshots, svc) }
/>}
{attachments
.map((embedding: any, index: any) => <LinkButton
key={ `attachment-${index}` }
Expand Down
Loading