Skip to content

Commit 429ee25

Browse files
committed
VueUiGauge add e2e component test
1 parent b504f1f commit 429ee25

File tree

5 files changed

+255
-7
lines changed

5 files changed

+255
-7
lines changed

cypress/downloads/Title.pdf

-333 KB
Binary file not shown.

cypress/downloads/Title.xlsx

-16.1 KB
Binary file not shown.

cypress/fixtures/gauge.json

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{
2+
"dataset": {
3+
"base": 100,
4+
"value": 4.2,
5+
"series": [
6+
{
7+
"from": 0,
8+
"to": 3,
9+
"color": "#3366cc"
10+
},
11+
{
12+
"from": 3,
13+
"to": 4,
14+
"color": "#dc3912"
15+
},
16+
{
17+
"from": 4,
18+
"to": 5,
19+
"color": "#ff9900"
20+
}
21+
]
22+
},
23+
"config": {
24+
"style": {
25+
"fontFamily": "inherit",
26+
"chart": {
27+
"backgroundColor": "#FFFFFF",
28+
"color": "#2D353C",
29+
"animation": {
30+
"use": true,
31+
"speed": 1,
32+
"acceleration": 1
33+
},
34+
"layout": {
35+
"useDiv": false,
36+
"track": {
37+
"size": 1,
38+
"useGradient": true,
39+
"gradientIntensity": 40
40+
},
41+
"markers": {
42+
"size": 1,
43+
"color": "#2D353C",
44+
"strokeWidth": 1,
45+
"stroke": "#2D353C",
46+
"backgroundColor": "#FFFFFF",
47+
"bold": true,
48+
"fontSizeRatio": 1,
49+
"offsetY": 0,
50+
"roundingValue": 0
51+
},
52+
"pointer": {
53+
"size": 1,
54+
"stroke": "#2D353C",
55+
"strokeWidth": 12,
56+
"useRatingColor": true,
57+
"color": "#CCCCCC",
58+
"circle": {
59+
"radius": 10,
60+
"stroke": "#2D353C",
61+
"strokeWidth": 2,
62+
"color": "#FFFFFF"
63+
}
64+
}
65+
},
66+
"legend": {
67+
"fontSize": 48,
68+
"prefix": "",
69+
"suffix": "",
70+
"roundingValue": 1,
71+
"showPlusSymbol": true,
72+
"useRatingColor": true,
73+
"color": "#2D353C"
74+
},
75+
"title": {
76+
"text": "Title",
77+
"color": "#2D353C",
78+
"fontSize": 20,
79+
"bold": true,
80+
"subtitle": {
81+
"color": "#A1A1A1",
82+
"text": "Subtitle",
83+
"fontSize": 16,
84+
"bold": false
85+
}
86+
}
87+
}
88+
},
89+
"userOptions": {
90+
"show": true,
91+
"title": "options",
92+
"labels": {
93+
"useDiv": "Title inside",
94+
"showTable": "Show table"
95+
}
96+
},
97+
"translations": {
98+
"base": "Base"
99+
}
100+
}
101+
}

src/components/vue-ui-gauge.cy.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import VueUiGauge from './vue-ui-gauge.vue'
2+
3+
4+
describe('<VueUiGauge />', () => {
5+
beforeEach(function () {
6+
cy.fixture('gauge.json').as('fixture');
7+
cy.viewport(400, 420);
8+
});
9+
10+
function updateConfigInFixture(modifiedConfig) {
11+
cy.get('@fixture').then((fixture) => {
12+
const updatedFixture = { ...fixture, config: modifiedConfig };
13+
cy.wrap(updatedFixture).as('fixture');
14+
});
15+
}
16+
17+
it('renders with different config attributes', function () {
18+
cy.get('@fixture').then((fixture) => {
19+
cy.mount(VueUiGauge, {
20+
props: {
21+
dataset: fixture.dataset,
22+
config: fixture.config
23+
}
24+
});
25+
26+
27+
28+
cy.get(`[data-cy="gauge-text-title"]`)
29+
.should('exist')
30+
.contains(`${fixture.config.style.chart.title.text}`);
31+
32+
cy.get(`[data-cy="gauge-text-subtitle"]`)
33+
.should('exist')
34+
.contains(`${fixture.config.style.chart.title.subtitle.text}`);
35+
36+
cy.get(`[data-cy="gauge-text-base"]`)
37+
.should('exist')
38+
.contains(`${fixture.config.translations.base} : ${fixture.dataset.base}`);
39+
40+
cy.get(`[data-cy="gauge-summary"]`).click();
41+
cy.get(`[data-cy="gauge-checkbox-title"]`).uncheck();
42+
cy.get(`[data-cy="gauge-summary"]`).click();
43+
44+
45+
cy.get(`[data-cy="gauge-div-title"]`)
46+
.should('exist')
47+
.contains(`${fixture.config.style.chart.title.text}`);
48+
49+
cy.get(`[data-cy="gauge-div-subtitle"]`)
50+
.should('exist')
51+
.contains(`${fixture.config.style.chart.title.subtitle.text}`);
52+
53+
cy.get(`[data-cy="gauge-div-base"]`)
54+
.should('exist')
55+
.contains(`${fixture.config.translations.base} : ${fixture.dataset.base}`);
56+
57+
for (let i = 0; i < fixture.dataset.series.length; i += 1) {
58+
cy.get(`[data-cy="gauge-arc-${i}"]`).then(($arc) => {
59+
cy.wrap($arc)
60+
.should('exist');
61+
62+
cy.wrap($arc)
63+
.invoke('attr', 'stroke')
64+
.should('eq', fixture.dataset.series[i].color)
65+
});
66+
67+
cy.get(`[data-cy="gauge-step-marker-${i}"]`).should('exist');
68+
cy.get(`[data-cy="gauge-step-marker-label-${i}"]`)
69+
.should('exist')
70+
.contains(`${fixture.dataset.series[i].from.toFixed(fixture.config.style.chart.layout.markers.roundingValue)}`)
71+
}
72+
73+
cy.get(`[data-cy="gauge-step-marker-last"]`).should('exist');
74+
cy.get(`[data-cy="gauge-step-marker-label-last"]`)
75+
.should('exist')
76+
.contains(`${fixture.dataset.series.at(-1).to.toFixed(fixture.config.style.chart.layout.markers.roundingValue)}`);
77+
78+
79+
cy.get(`[data-cy="gauge-pointer-border"]`).then(($pointer) => {
80+
cy.wrap($pointer)
81+
.should('exist')
82+
.invoke('attr', 'stroke')
83+
.should('eq', fixture.config.style.chart.layout.pointer.stroke);
84+
85+
cy.wrap($pointer)
86+
.invoke('attr', 'stroke-width')
87+
.should('eq', String(fixture.config.style.chart.layout.pointer.strokeWidth))
88+
});
89+
90+
function getColor(number) {
91+
for (let i = 0; i < fixture.dataset.series.length; i += 1) {
92+
if (number >= fixture.dataset.series[i].from && number < fixture.dataset.series[i].to) {
93+
return fixture.dataset.series[i].color;
94+
}
95+
}
96+
return null;
97+
}
98+
99+
cy.wait(500);
100+
cy.get(`[data-cy="gauge-pointer"]`).then(($pointer) => {
101+
cy.wrap($pointer)
102+
.should('exist')
103+
.invoke('attr', 'stroke')
104+
.should('eq', getColor(fixture.dataset.value))
105+
});
106+
107+
cy.get(`[data-cy="gauge-pointer-circle"]`).then(($circle) => {
108+
cy.wrap($circle)
109+
.should('exist')
110+
.invoke('attr', 'fill')
111+
.should('eq', fixture.config.style.chart.layout.pointer.circle.color);
112+
113+
cy.wrap($circle)
114+
.invoke('attr', 'r')
115+
.should('eq', String(fixture.config.style.chart.layout.pointer.circle.radius));
116+
117+
cy.wrap($circle)
118+
.invoke('attr', 'stroke-width')
119+
.should('eq', String(fixture.config.style.chart.layout.pointer.circle.strokeWidth));
120+
121+
cy.wrap($circle)
122+
.invoke('attr', 'stroke')
123+
.should('eq', fixture.config.style.chart.layout.pointer.circle.stroke);
124+
})
125+
126+
cy.get(`[data-cy="gauge-summary"]`).click();
127+
128+
cy.get(`[data-cy="gauge-pdf"]`).click();
129+
cy.wait(2000);
130+
cy.readFile(`cypress\\Downloads\\${fixture.config.style.chart.title.text}.pdf`);
131+
132+
cy.clearDownloads();
133+
});
134+
});
135+
})

src/components/vue-ui-gauge.vue

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup>
2-
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
2+
import { ref, computed, onMounted } from "vue";
33
import { treeShake, palette, rotateMatrix, addVector, matrixTimes, opacity, convertColorToHex, convertConfigColors } from "../lib.js";
44
import pdf from "../pdf";
55
import mainConfig from "../default_configs.json";
@@ -265,27 +265,27 @@ defineExpose({
265265
>
266266
<!-- TITLE AS DIV -->
267267
<div v-if="(!mutableConfig.inside || isPrinting) && gaugeConfig.style.chart.title.text" :style="`width:100%;background:${gaugeConfig.style.chart.backgroundColor};padding-bottom:12px;${gaugeConfig.userOptions.show ? 'padding-top:36px' : ''}`">
268-
<div :style="`width:100%;text-align:center;color:${gaugeConfig.style.chart.title.color};font-size:${gaugeConfig.style.chart.title.fontSize}px;font-weight:${gaugeConfig.style.chart.title.bold ? 'bold': ''}`">
268+
<div data-cy="gauge-div-title" :style="`width:100%;text-align:center;color:${gaugeConfig.style.chart.title.color};font-size:${gaugeConfig.style.chart.title.fontSize}px;font-weight:${gaugeConfig.style.chart.title.bold ? 'bold': ''}`">
269269
{{ gaugeConfig.style.chart.title.text }}
270270
</div>
271-
<div v-if="gaugeConfig.style.chart.title.subtitle.text" :style="`width:100%;text-align:center;color:${gaugeConfig.style.chart.title.subtitle.color};font-size:${gaugeConfig.style.chart.title.subtitle.fontSize}px;font-weight:${gaugeConfig.style.chart.title.subtitle.bold ? 'bold': ''}`">
271+
<div data-cy="gauge-div-subtitle" v-if="gaugeConfig.style.chart.title.subtitle.text" :style="`width:100%;text-align:center;color:${gaugeConfig.style.chart.title.subtitle.color};font-size:${gaugeConfig.style.chart.title.subtitle.fontSize}px;font-weight:${gaugeConfig.style.chart.title.subtitle.bold ? 'bold': ''}`">
272272
{{ gaugeConfig.style.chart.title.subtitle.text }}
273273
</div>
274-
<div v-if="!isNaN(dataset.base)" :style="`width:100%;text-align:center;color:${gaugeConfig.style.chart.title.subtitle.color};font-size:${gaugeConfig.style.chart.title.subtitle.fontSize}px;font-weight:${gaugeConfig.style.chart.title.subtitle.bold ? 'bold': ''}`">
274+
<div data-cy="gauge-div-base" v-if="!isNaN(dataset.base)" :style="`width:100%;text-align:center;color:${gaugeConfig.style.chart.title.subtitle.color};font-size:${gaugeConfig.style.chart.title.subtitle.fontSize}px;font-weight:${gaugeConfig.style.chart.title.subtitle.bold ? 'bold': ''}`">
275275
{{ gaugeConfig.translations.base }} : {{ dataset.base }}
276276
</div>
277277
</div>
278278

279279
<!-- OPTIONS -->
280280
<details class="vue-ui-gauge-user-options" :style="`background:${gaugeConfig.style.chart.backgroundColor};color:${gaugeConfig.style.chart.color}`" data-html2canvas-ignore v-if="gaugeConfig.userOptions.show" ref="details">
281-
<summary :style="`background:${gaugeConfig.style.chart.backgroundColor};color:${gaugeConfig.style.chart.color}`">{{ gaugeConfig.userOptions.title }}</summary>
281+
<summary data-cy="gauge-summary" :style="`background:${gaugeConfig.style.chart.backgroundColor};color:${gaugeConfig.style.chart.color}`">{{ gaugeConfig.userOptions.title }}</summary>
282282
<div class="vue-ui-gauge-user-options-items" :style="`background:${gaugeConfig.style.chart.backgroundColor};color:${gaugeConfig.style.chart.color}`">
283283
<div class="vue-ui-gauge-user-option-item">
284-
<input type="checkbox" :id="`vue-ui-gauge-option-title_${uid}`" :name="`vue-ui-gauge-option-title_${uid}`"
284+
<input data-cy="gauge-checkbox-title" type="checkbox" :id="`vue-ui-gauge-option-title_${uid}`" :name="`vue-ui-gauge-option-title_${uid}`"
285285
v-model="mutableConfig.inside">
286286
<label :for="`vue-ui-gauge-option-title_${uid}`">{{ gaugeConfig.userOptions.labels.useDiv }}</label>
287287
</div>
288-
<button class="vue-ui-gauge-button" @click="generatePdf" :disabled="isPrinting" style="margin-top:12px" :style="`color:${gaugeConfig.style.chart.color}`">
288+
<button data-cy="gauge-pdf" class="vue-ui-gauge-button" @click="generatePdf" :disabled="isPrinting" style="margin-top:12px" :style="`color:${gaugeConfig.style.chart.color}`">
289289
<svg class="vue-ui-gauge-print-icon" xmlns="http://www.w3.org/2000/svg" v-if="isPrinting" width="20" height="20" viewBox="0 0 24 24" stroke-width="1.5" :stroke="gaugeConfig.style.chart.color" fill="none" stroke-linecap="round" stroke-linejoin="round">
290290
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
291291
<path d="M18 16v.01" />
@@ -313,6 +313,7 @@ defineExpose({
313313
<!-- TITLE AS G -->
314314
<g v-if="gaugeConfig.style.chart.title.text && mutableConfig.inside && !isPrinting">
315315
<text
316+
data-cy="gauge-text-title"
316317
:font-size="(gaugeConfig.style.chart.title.fontSize * 1.5)"
317318
:fill="gaugeConfig.style.chart.title.color"
318319
:x="svg.width / 2"
@@ -323,6 +324,7 @@ defineExpose({
323324
{{ gaugeConfig.style.chart.title.text }}
324325
</text>
325326
<text
327+
data-cy="gauge-text-subtitle"
326328
v-if="gaugeConfig.style.chart.title.subtitle.text"
327329
:font-size="(gaugeConfig.style.chart.title.subtitle.fontSize * 1.5)"
328330
:fill="gaugeConfig.style.chart.title.subtitle.color"
@@ -334,6 +336,7 @@ defineExpose({
334336
{{ gaugeConfig.style.chart.title.subtitle.text }}
335337
</text>
336338
<text
339+
data-cy="gauge-text-base"
337340
v-if="!isNaN(dataset.base)"
338341
:font-size="(gaugeConfig.style.chart.title.subtitle.fontSize * 1.5)"
339342
:fill="gaugeConfig.style.chart.title.subtitle.color"
@@ -349,6 +352,7 @@ defineExpose({
349352
<!-- ARC STEPS -->
350353
<path
351354
v-for="(arc, i) in makeDonut(mutableDataset, svg.width / 2, svg.height * 0.7, svg.width / 2.5, svg.width / 2.5)"
355+
:data-cy="`gauge-arc-${i}`"
352356
:key="`arc_${i}`"
353357
:d="arc.path"
354358
fill="none"
@@ -367,6 +371,7 @@ defineExpose({
367371
<!-- STEP MARKERS -->
368372
<circle
369373
v-for="(arc, i) in makeDonut(mutableDataset, svg.width / 2, svg.height * 0.7, svg.width / 2.5, svg.width / 2.5)"
374+
:data-cy="`gauge-step-marker-${i}`"
370375
:cx="arc.center.startX"
371376
:cy="i === 0 ? arc.center.startY + 5 : arc.center.startY"
372377
:r="(svg.width / 31) * gaugeConfig.style.chart.layout.track.size * gaugeConfig.style.chart.layout.markers.size"
@@ -375,6 +380,7 @@ defineExpose({
375380
:stroke-width="gaugeConfig.style.chart.layout.markers.strokeWidth"
376381
/>
377382
<circle
383+
data-cy="gauge-step-marker-last"
378384
:cx="svg.width * 0.9"
379385
:cy="svg.height * 0.69"
380386
:r="(svg.width / 31) * gaugeConfig.style.chart.layout.track.size * gaugeConfig.style.chart.layout.markers.size"
@@ -384,6 +390,7 @@ defineExpose({
384390
/>
385391
<text
386392
v-for="(arc, i) in makeDonut(mutableDataset, svg.width / 2, svg.height * 0.7, svg.width / 2.5, svg.width / 2.5)"
393+
:data-cy="`gauge-step-marker-label-${i}`"
387394
:x="arc.center.startX"
388395
:y="calcMarkerPositionY(i, arc.center.startY, arc.from) + gaugeConfig.style.chart.layout.markers.offsetY"
389396
text-anchor="middle"
@@ -394,6 +401,7 @@ defineExpose({
394401
{{ arc.from.toFixed(gaugeConfig.style.chart.layout.markers.roundingValue) }}
395402
</text>
396403
<text
404+
data-cy="gauge-step-marker-label-last"
397405
:x="svg.width * 0.9"
398406
:y="calcMarkerPositionY(1, svg.height * 0.69, max) + gaugeConfig.style.chart.layout.markers.offsetY"
399407
text-anchor="middle"
@@ -406,6 +414,7 @@ defineExpose({
406414

407415
<!-- GAUGE POINTER -->
408416
<line
417+
data-cy="gauge-pointer-border"
409418
v-if="!isNaN(pointer.x2)"
410419
:x1="pointer.x1"
411420
:y1="pointer.y1"
@@ -416,6 +425,7 @@ defineExpose({
416425
stroke-linecap="round"
417426
/>
418427
<line
428+
data-cy="gauge-pointer"
419429
v-if="!isNaN(pointer.x2)"
420430
:x1="pointer.x1"
421431
:y1="pointer.y1"
@@ -426,6 +436,7 @@ defineExpose({
426436
:stroke-width="gaugeConfig.style.chart.layout.pointer.strokeWidth * 0.7"
427437
/>
428438
<circle
439+
data-cy="gauge-pointer-circle"
429440
:cx="svg.width / 2"
430441
:cy="(svg.height) * 0.69"
431442
:fill="gaugeConfig.style.chart.layout.pointer.circle.color"
@@ -436,6 +447,7 @@ defineExpose({
436447

437448
<!-- GAUGE RATING -->
438449
<text
450+
data-cy="gauge-score"
439451
:x="svg.width / 2"
440452
:y="(svg.height) * 0.9"
441453
text-anchor="middle"

0 commit comments

Comments
 (0)