@fdm-monster/client-next 2.2.2 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.yarn/install-state.gz +0 -0
- package/README.md +19 -0
- package/RELEASE_NOTES.MD +10 -0
- package/dist/assets/{index-BlOaSQti.js → index-BAB7cJ3l.js} +52 -52
- package/dist/assets/{index-BlOaSQti.js.map → index-BAB7cJ3l.js.map} +1 -1
- package/dist/assets/index-DfA7W6iO.css +1 -0
- package/dist/index.html +3 -3
- package/package.json +21 -2
- package/screenshots/COVERAGE.md +383 -0
- package/screenshots/README.md +431 -0
- package/screenshots/fixtures/api-mock.ts +699 -0
- package/screenshots/fixtures/data/auth.fixtures.ts +79 -0
- package/screenshots/fixtures/data/cameras.fixtures.ts +48 -0
- package/screenshots/fixtures/data/files.fixtures.ts +56 -0
- package/screenshots/fixtures/data/floors.fixtures.ts +39 -0
- package/screenshots/fixtures/data/jobs.fixtures.ts +172 -0
- package/screenshots/fixtures/data/printers.fixtures.ts +132 -0
- package/screenshots/fixtures/data/settings.fixtures.ts +62 -0
- package/screenshots/fixtures/socketio-mock.ts +76 -0
- package/screenshots/fixtures/test-fixtures.ts +112 -0
- package/screenshots/helpers/dialog.helper.ts +196 -0
- package/screenshots/helpers/form.helper.ts +207 -0
- package/screenshots/helpers/navigation.helper.ts +191 -0
- package/screenshots/playwright.screenshots.config.ts +70 -0
- package/screenshots/suites/00-example.screenshots.spec.ts +29 -0
- package/screenshots/suites/01-auth.screenshots.spec.ts +130 -0
- package/screenshots/suites/02-dashboard.screenshots.spec.ts +106 -0
- package/screenshots/suites/03-printer-grid.screenshots.spec.ts +160 -0
- package/screenshots/suites/04-printer-list.screenshots.spec.ts +184 -0
- package/screenshots/suites/05-camera-grid.screenshots.spec.ts +127 -0
- package/screenshots/suites/06-print-jobs.screenshots.spec.ts +139 -0
- package/screenshots/suites/07-queue.screenshots.spec.ts +86 -0
- package/screenshots/suites/08-files.screenshots.spec.ts +142 -0
- package/screenshots/suites/09-settings.screenshots.spec.ts +130 -0
- package/screenshots/suites/10-panels-dialogs.screenshots.spec.ts +245 -0
- package/screenshots/utils.ts +216 -0
- package/vitest.config.ts +8 -0
- package/dist/assets/index-TeWdSn_6.css +0 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { test, expect } from '../fixtures/test-fixtures';
|
|
2
|
+
import { captureFullPage } from '../utils';
|
|
3
|
+
import { createNavigationHelper } from '../helpers/navigation.helper';
|
|
4
|
+
import { createDialogHelper } from '../helpers/dialog.helper';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Camera Grid Screenshots
|
|
8
|
+
* Captures: Camera grid, creating camera
|
|
9
|
+
*/
|
|
10
|
+
test.describe('Camera Grid Screenshots', () => {
|
|
11
|
+
test.beforeEach(async ({ apiMock }) => {
|
|
12
|
+
await apiMock.mockAllEndpoints({ loginRequired: false });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('01-camera-grid-view', async ({ authenticatedPage }) => {
|
|
16
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
17
|
+
await nav.goToCameras();
|
|
18
|
+
|
|
19
|
+
// Wait for camera grid to load
|
|
20
|
+
await authenticatedPage.waitForSelector(
|
|
21
|
+
'[data-testid="camera-grid"], .camera-grid, main',
|
|
22
|
+
{ timeout: 5000 }
|
|
23
|
+
).catch(() => {});
|
|
24
|
+
|
|
25
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
26
|
+
|
|
27
|
+
await captureFullPage(authenticatedPage, 'camera-grid-view.png', 'cameras');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('02-camera-grid-empty', async ({ authenticatedPage, apiMock }) => {
|
|
31
|
+
// Mock with empty data
|
|
32
|
+
await apiMock.mockAllEndpoints({ loginRequired: false, emptyData: true });
|
|
33
|
+
|
|
34
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
35
|
+
await nav.goToCameras();
|
|
36
|
+
|
|
37
|
+
await authenticatedPage.waitForSelector(
|
|
38
|
+
'[data-testid="empty-state"], .empty-state, main',
|
|
39
|
+
{ timeout: 5000 }
|
|
40
|
+
).catch(() => {});
|
|
41
|
+
|
|
42
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
43
|
+
|
|
44
|
+
await captureFullPage(authenticatedPage, 'camera-grid-empty.png', 'cameras');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('03-create-camera-dialog', async ({ authenticatedPage }) => {
|
|
48
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
49
|
+
await nav.goToCameras();
|
|
50
|
+
|
|
51
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
52
|
+
|
|
53
|
+
// Click add/create camera button
|
|
54
|
+
const addBtn = authenticatedPage.locator('button').filter({ hasText: /add|create|new/i }).first();
|
|
55
|
+
await addBtn.click().catch(() => {});
|
|
56
|
+
|
|
57
|
+
// Wait for dialog
|
|
58
|
+
const dialog = createDialogHelper(authenticatedPage);
|
|
59
|
+
await dialog.waitForDialog();
|
|
60
|
+
|
|
61
|
+
await authenticatedPage.waitForTimeout(500);
|
|
62
|
+
|
|
63
|
+
await captureFullPage(authenticatedPage, 'create-camera-dialog.png', 'cameras');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('04-create-camera-dialog-filled', async ({ authenticatedPage }) => {
|
|
67
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
68
|
+
await nav.goToCameras();
|
|
69
|
+
|
|
70
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
71
|
+
|
|
72
|
+
// Click add camera button
|
|
73
|
+
const addBtn = authenticatedPage.locator('button').filter({ hasText: /add|create|new/i }).first();
|
|
74
|
+
await addBtn.click().catch(() => {});
|
|
75
|
+
|
|
76
|
+
// Wait for dialog
|
|
77
|
+
const dialog = createDialogHelper(authenticatedPage);
|
|
78
|
+
await dialog.waitForDialog();
|
|
79
|
+
|
|
80
|
+
await authenticatedPage.waitForTimeout(500);
|
|
81
|
+
|
|
82
|
+
// Fill form fields
|
|
83
|
+
const inputs = authenticatedPage.locator('.v-dialog input[type="text"], .v-dialog input[type="url"]');
|
|
84
|
+
if (await inputs.count() > 0) {
|
|
85
|
+
await inputs.nth(0).fill('Main Workshop Camera');
|
|
86
|
+
if (await inputs.count() > 1) {
|
|
87
|
+
await inputs.nth(1).fill('http://192.168.1.100/webcam/?action=stream');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
await authenticatedPage.waitForTimeout(500);
|
|
92
|
+
|
|
93
|
+
await captureFullPage(authenticatedPage, 'create-camera-dialog-filled.png', 'cameras');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('05-camera-card-with-stream', async ({ authenticatedPage }) => {
|
|
97
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
98
|
+
await nav.goToCameras();
|
|
99
|
+
|
|
100
|
+
await authenticatedPage.waitForTimeout(1500);
|
|
101
|
+
|
|
102
|
+
// Focus on a single camera card if visible
|
|
103
|
+
const cameraCard = authenticatedPage.locator('.camera-card, [data-testid="camera-card"]').first();
|
|
104
|
+
if (await cameraCard.isVisible().catch(() => false)) {
|
|
105
|
+
await cameraCard.hover();
|
|
106
|
+
await authenticatedPage.waitForTimeout(500);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
await captureFullPage(authenticatedPage, 'camera-card-with-stream.png', 'cameras');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('06-camera-fullscreen-view', async ({ authenticatedPage }) => {
|
|
113
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
114
|
+
await nav.goToCameras();
|
|
115
|
+
|
|
116
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
117
|
+
|
|
118
|
+
// Click on a camera to open fullscreen/expanded view
|
|
119
|
+
const cameraCard = authenticatedPage.locator('.camera-card, [data-testid="camera-card"]').first();
|
|
120
|
+
if (await cameraCard.isVisible().catch(() => false)) {
|
|
121
|
+
await cameraCard.click();
|
|
122
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await captureFullPage(authenticatedPage, 'camera-fullscreen-view.png', 'cameras');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { test, expect } from '../fixtures/test-fixtures';
|
|
2
|
+
import { captureFullPage } from '../utils';
|
|
3
|
+
import { createNavigationHelper } from '../helpers/navigation.helper';
|
|
4
|
+
import { createDialogHelper } from '../helpers/dialog.helper';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Print Jobs Screenshots
|
|
8
|
+
* Captures: Jobs list, job dialog with details
|
|
9
|
+
*/
|
|
10
|
+
test.describe('Print Jobs Screenshots', () => {
|
|
11
|
+
test.beforeEach(async ({ apiMock }) => {
|
|
12
|
+
await apiMock.mockAllEndpoints({ loginRequired: false });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('01-print-jobs-list', async ({ authenticatedPage }) => {
|
|
16
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
17
|
+
await nav.goToJobs();
|
|
18
|
+
|
|
19
|
+
// Wait for jobs list to load
|
|
20
|
+
await authenticatedPage.waitForSelector(
|
|
21
|
+
'[data-testid="jobs-list"], .jobs-list, table, .v-data-table',
|
|
22
|
+
{ timeout: 5000 }
|
|
23
|
+
).catch(() => {});
|
|
24
|
+
|
|
25
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
26
|
+
|
|
27
|
+
await captureFullPage(authenticatedPage, 'print-jobs-list.png', 'jobs');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('02-print-jobs-empty', async ({ authenticatedPage, apiMock }) => {
|
|
31
|
+
// Mock with empty data
|
|
32
|
+
await apiMock.mockAllEndpoints({ loginRequired: false, emptyData: true });
|
|
33
|
+
|
|
34
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
35
|
+
await nav.goToJobs();
|
|
36
|
+
|
|
37
|
+
await authenticatedPage.waitForSelector(
|
|
38
|
+
'[data-testid="empty-state"], .empty-state, main',
|
|
39
|
+
{ timeout: 5000 }
|
|
40
|
+
).catch(() => {});
|
|
41
|
+
|
|
42
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
43
|
+
|
|
44
|
+
await captureFullPage(authenticatedPage, 'print-jobs-empty.png', 'jobs');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('03-job-details-dialog', async ({ authenticatedPage }) => {
|
|
48
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
49
|
+
await nav.goToJobs();
|
|
50
|
+
|
|
51
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
52
|
+
|
|
53
|
+
// Click on first job row to open details
|
|
54
|
+
const jobRow = authenticatedPage.locator('tr, .v-list-item, .job-item').first();
|
|
55
|
+
if (await jobRow.isVisible().catch(() => false)) {
|
|
56
|
+
await jobRow.click();
|
|
57
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
await captureFullPage(authenticatedPage, 'job-details-dialog.png', 'jobs');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('04-job-details-with-statistics', async ({ authenticatedPage }) => {
|
|
64
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
65
|
+
await nav.goToJobs();
|
|
66
|
+
|
|
67
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
68
|
+
|
|
69
|
+
// Click on a completed job to see full statistics
|
|
70
|
+
const completedJob = authenticatedPage.locator('tr, .job-item').filter({ hasText: /completed/i }).first();
|
|
71
|
+
if (await completedJob.isVisible().catch(() => false)) {
|
|
72
|
+
await completedJob.click();
|
|
73
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
74
|
+
} else {
|
|
75
|
+
// Fallback to first job
|
|
76
|
+
const jobRow = authenticatedPage.locator('tr, .job-item').first();
|
|
77
|
+
await jobRow.click().catch(() => {});
|
|
78
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await captureFullPage(authenticatedPage, 'job-details-with-statistics.png', 'jobs');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('05-jobs-filter-panel', async ({ authenticatedPage }) => {
|
|
85
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
86
|
+
await nav.goToJobs();
|
|
87
|
+
|
|
88
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
89
|
+
|
|
90
|
+
// Look for filter button or panel
|
|
91
|
+
const filterBtn = authenticatedPage.locator('button').filter({ hasText: /filter/i }).first();
|
|
92
|
+
if (await filterBtn.isVisible().catch(() => false)) {
|
|
93
|
+
await filterBtn.click();
|
|
94
|
+
await authenticatedPage.waitForTimeout(500);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await captureFullPage(authenticatedPage, 'jobs-filter-panel.png', 'jobs');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('06-jobs-by-status-completed', async ({ authenticatedPage }) => {
|
|
101
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
102
|
+
await nav.goToJobs();
|
|
103
|
+
|
|
104
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
105
|
+
|
|
106
|
+
// Try to filter by completed status
|
|
107
|
+
const statusFilter = authenticatedPage.locator('select, .v-select').filter({ hasText: /status/i }).first();
|
|
108
|
+
if (await statusFilter.isVisible().catch(() => false)) {
|
|
109
|
+
await statusFilter.click();
|
|
110
|
+
await authenticatedPage.waitForTimeout(300);
|
|
111
|
+
|
|
112
|
+
const completedOption = authenticatedPage.locator('.v-list-item').filter({ hasText: /completed/i }).first();
|
|
113
|
+
await completedOption.click().catch(() => {});
|
|
114
|
+
await authenticatedPage.waitForTimeout(500);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
await captureFullPage(authenticatedPage, 'jobs-by-status-completed.png', 'jobs');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('07-jobs-by-status-failed', async ({ authenticatedPage }) => {
|
|
121
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
122
|
+
await nav.goToJobs();
|
|
123
|
+
|
|
124
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
125
|
+
|
|
126
|
+
// Try to filter by failed status
|
|
127
|
+
const statusFilter = authenticatedPage.locator('select, .v-select').filter({ hasText: /status/i }).first();
|
|
128
|
+
if (await statusFilter.isVisible().catch(() => false)) {
|
|
129
|
+
await statusFilter.click();
|
|
130
|
+
await authenticatedPage.waitForTimeout(300);
|
|
131
|
+
|
|
132
|
+
const failedOption = authenticatedPage.locator('.v-list-item').filter({ hasText: /failed/i }).first();
|
|
133
|
+
await failedOption.click().catch(() => {});
|
|
134
|
+
await authenticatedPage.waitForTimeout(500);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
await captureFullPage(authenticatedPage, 'jobs-by-status-failed.png', 'jobs');
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { test, expect } from '../fixtures/test-fixtures';
|
|
2
|
+
import { captureFullPage } from '../utils';
|
|
3
|
+
import { createNavigationHelper } from '../helpers/navigation.helper';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Queue Screenshots
|
|
7
|
+
* Captures: Queue view with pending jobs
|
|
8
|
+
*/
|
|
9
|
+
test.describe('Queue Screenshots', () => {
|
|
10
|
+
test.beforeEach(async ({ apiMock }) => {
|
|
11
|
+
await apiMock.mockAllEndpoints({ loginRequired: false });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('01-queue-view', async ({ authenticatedPage }) => {
|
|
15
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
16
|
+
await nav.goToQueue();
|
|
17
|
+
|
|
18
|
+
// Wait for queue to load
|
|
19
|
+
await authenticatedPage.waitForSelector(
|
|
20
|
+
'[data-testid="queue"], .queue, main',
|
|
21
|
+
{ timeout: 5000 }
|
|
22
|
+
).catch(() => {});
|
|
23
|
+
|
|
24
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
25
|
+
|
|
26
|
+
await captureFullPage(authenticatedPage, 'queue-view.png', 'queue');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('02-queue-empty', async ({ authenticatedPage, apiMock }) => {
|
|
30
|
+
// Mock with empty data
|
|
31
|
+
await apiMock.mockAllEndpoints({ loginRequired: false, emptyData: true });
|
|
32
|
+
|
|
33
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
34
|
+
await nav.goToQueue();
|
|
35
|
+
|
|
36
|
+
await authenticatedPage.waitForSelector(
|
|
37
|
+
'[data-testid="empty-state"], .empty-state, main',
|
|
38
|
+
{ timeout: 5000 }
|
|
39
|
+
).catch(() => {});
|
|
40
|
+
|
|
41
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
42
|
+
|
|
43
|
+
await captureFullPage(authenticatedPage, 'queue-empty.png', 'queue');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('03-queue-with-jobs', async ({ authenticatedPage }) => {
|
|
47
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
48
|
+
await nav.goToQueue();
|
|
49
|
+
|
|
50
|
+
await authenticatedPage.waitForTimeout(1500);
|
|
51
|
+
|
|
52
|
+
await captureFullPage(authenticatedPage, 'queue-with-jobs.png', 'queue');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('04-queue-job-context-menu', async ({ authenticatedPage }) => {
|
|
56
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
57
|
+
await nav.goToQueue();
|
|
58
|
+
|
|
59
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
60
|
+
|
|
61
|
+
// Right-click on a queue item
|
|
62
|
+
const queueItem = authenticatedPage.locator('.queue-item, [data-testid="queue-item"], tr').first();
|
|
63
|
+
if (await queueItem.isVisible().catch(() => false)) {
|
|
64
|
+
await queueItem.click({ button: 'right' });
|
|
65
|
+
await authenticatedPage.waitForTimeout(500);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
await captureFullPage(authenticatedPage, 'queue-job-context-menu.png', 'queue');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('05-queue-reorder-drag', async ({ authenticatedPage }) => {
|
|
72
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
73
|
+
await nav.goToQueue();
|
|
74
|
+
|
|
75
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
76
|
+
|
|
77
|
+
// Hover over a queue item to show drag handle
|
|
78
|
+
const queueItem = authenticatedPage.locator('.queue-item, [data-testid="queue-item"]').first();
|
|
79
|
+
if (await queueItem.isVisible().catch(() => false)) {
|
|
80
|
+
await queueItem.hover();
|
|
81
|
+
await authenticatedPage.waitForTimeout(500);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
await captureFullPage(authenticatedPage, 'queue-reorder-drag.png', 'queue');
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { test, expect } from '../fixtures/test-fixtures';
|
|
2
|
+
import { captureFullPage } from '../utils';
|
|
3
|
+
import { createNavigationHelper } from '../helpers/navigation.helper';
|
|
4
|
+
import { createDialogHelper } from '../helpers/dialog.helper';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Files Screenshots
|
|
8
|
+
* Captures: File browser, file operations
|
|
9
|
+
*/
|
|
10
|
+
test.describe('Files Screenshots', () => {
|
|
11
|
+
test.beforeEach(async ({ apiMock }) => {
|
|
12
|
+
await apiMock.mockAllEndpoints({ loginRequired: false });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('01-files-browser', async ({ authenticatedPage }) => {
|
|
16
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
17
|
+
await nav.goToFiles();
|
|
18
|
+
|
|
19
|
+
// Wait for file browser to load
|
|
20
|
+
await authenticatedPage.waitForSelector(
|
|
21
|
+
'[data-testid="files-browser"], .files-browser, main',
|
|
22
|
+
{ timeout: 5000 }
|
|
23
|
+
).catch(() => {});
|
|
24
|
+
|
|
25
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
26
|
+
|
|
27
|
+
await captureFullPage(authenticatedPage, 'files-browser.png', 'files');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('02-files-empty', async ({ authenticatedPage, apiMock }) => {
|
|
31
|
+
// Mock with empty data
|
|
32
|
+
await apiMock.mockAllEndpoints({ loginRequired: false, emptyData: true });
|
|
33
|
+
|
|
34
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
35
|
+
await nav.goToFiles();
|
|
36
|
+
|
|
37
|
+
await authenticatedPage.waitForSelector(
|
|
38
|
+
'[data-testid="empty-state"], .empty-state, main',
|
|
39
|
+
{ timeout: 5000 }
|
|
40
|
+
).catch(() => {});
|
|
41
|
+
|
|
42
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
43
|
+
|
|
44
|
+
await captureFullPage(authenticatedPage, 'files-empty.png', 'files');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('03-file-upload-dialog', async ({ authenticatedPage }) => {
|
|
48
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
49
|
+
await nav.goToFiles();
|
|
50
|
+
|
|
51
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
52
|
+
|
|
53
|
+
// Click upload button
|
|
54
|
+
const uploadBtn = authenticatedPage.locator('button').filter({ hasText: /upload/i }).first();
|
|
55
|
+
if (await uploadBtn.isVisible().catch(() => false)) {
|
|
56
|
+
await uploadBtn.click();
|
|
57
|
+
await authenticatedPage.waitForTimeout(500);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
await captureFullPage(authenticatedPage, 'file-upload-dialog.png', 'files');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('04-file-context-menu', async ({ authenticatedPage }) => {
|
|
64
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
65
|
+
await nav.goToFiles();
|
|
66
|
+
|
|
67
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
68
|
+
|
|
69
|
+
// Right-click on a file
|
|
70
|
+
const fileItem = authenticatedPage.locator('.file-item, [data-testid="file-item"], tr').filter({ hasText: /\.gcode|\.stl/i }).first();
|
|
71
|
+
if (await fileItem.isVisible().catch(() => false)) {
|
|
72
|
+
await fileItem.click({ button: 'right' });
|
|
73
|
+
await authenticatedPage.waitForTimeout(500);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
await captureFullPage(authenticatedPage, 'file-context-menu.png', 'files');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('05-file-details-dialog', async ({ authenticatedPage }) => {
|
|
80
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
81
|
+
await nav.goToFiles();
|
|
82
|
+
|
|
83
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
84
|
+
|
|
85
|
+
// Click on a file to open details
|
|
86
|
+
const fileItem = authenticatedPage.locator('.file-item, [data-testid="file-item"], tr').first();
|
|
87
|
+
if (await fileItem.isVisible().catch(() => false)) {
|
|
88
|
+
await fileItem.click();
|
|
89
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await captureFullPage(authenticatedPage, 'file-details-dialog.png', 'files');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('06-files-grid-view', async ({ authenticatedPage }) => {
|
|
96
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
97
|
+
await nav.goToFiles();
|
|
98
|
+
|
|
99
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
100
|
+
|
|
101
|
+
// Try to switch to grid view
|
|
102
|
+
const gridViewBtn = authenticatedPage.locator('button[aria-label*="grid" i], .view-toggle').first();
|
|
103
|
+
if (await gridViewBtn.isVisible().catch(() => false)) {
|
|
104
|
+
await gridViewBtn.click();
|
|
105
|
+
await authenticatedPage.waitForTimeout(500);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
await captureFullPage(authenticatedPage, 'files-grid-view.png', 'files');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('07-files-list-view', async ({ authenticatedPage }) => {
|
|
112
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
113
|
+
await nav.goToFiles();
|
|
114
|
+
|
|
115
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
116
|
+
|
|
117
|
+
// Try to switch to list view (may already be in list view)
|
|
118
|
+
const listViewBtn = authenticatedPage.locator('button[aria-label*="list" i], .view-toggle').first();
|
|
119
|
+
if (await listViewBtn.isVisible().catch(() => false)) {
|
|
120
|
+
await listViewBtn.click();
|
|
121
|
+
await authenticatedPage.waitForTimeout(500);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
await captureFullPage(authenticatedPage, 'files-list-view.png', 'files');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('08-file-print-dialog', async ({ authenticatedPage }) => {
|
|
128
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
129
|
+
await nav.goToFiles();
|
|
130
|
+
|
|
131
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
132
|
+
|
|
133
|
+
// Click print action on a file
|
|
134
|
+
const printBtn = authenticatedPage.locator('button').filter({ hasText: /print/i }).first();
|
|
135
|
+
if (await printBtn.isVisible().catch(() => false)) {
|
|
136
|
+
await printBtn.click();
|
|
137
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
await captureFullPage(authenticatedPage, 'file-print-dialog.png', 'files');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { test, expect } from '../fixtures/test-fixtures';
|
|
2
|
+
import { captureFullPage } from '../utils';
|
|
3
|
+
import { createNavigationHelper } from '../helpers/navigation.helper';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Settings Screenshots
|
|
7
|
+
* Captures: All settings pages based on actual routes from setting.constants.ts
|
|
8
|
+
*/
|
|
9
|
+
test.describe('Settings Screenshots', () => {
|
|
10
|
+
test.beforeEach(async ({ apiMock }) => {
|
|
11
|
+
await apiMock.mockAllEndpoints({ loginRequired: false });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('01-settings-overview', async ({ authenticatedPage }) => {
|
|
15
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
16
|
+
await nav.goToSettings();
|
|
17
|
+
|
|
18
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
19
|
+
|
|
20
|
+
await captureFullPage(authenticatedPage, 'settings-overview.png', 'settings');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('02-settings-floors', async ({ authenticatedPage }) => {
|
|
24
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
25
|
+
await nav.goToSettings('floors');
|
|
26
|
+
|
|
27
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
28
|
+
|
|
29
|
+
await captureFullPage(authenticatedPage, 'settings-floors.png', 'settings');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('03-settings-printer', async ({ authenticatedPage }) => {
|
|
33
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
34
|
+
await nav.goToSettings('printer');
|
|
35
|
+
|
|
36
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
37
|
+
|
|
38
|
+
await captureFullPage(authenticatedPage, 'settings-printer.png', 'settings');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('04-settings-emergency-commands', async ({ authenticatedPage }) => {
|
|
42
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
43
|
+
await nav.goToSettings('emergency-commands');
|
|
44
|
+
|
|
45
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
46
|
+
|
|
47
|
+
await captureFullPage(authenticatedPage, 'settings-emergency-commands.png', 'settings');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('05-settings-server-protection', async ({ authenticatedPage }) => {
|
|
51
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
52
|
+
await nav.goToSettings('server-protection');
|
|
53
|
+
|
|
54
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
55
|
+
|
|
56
|
+
await captureFullPage(authenticatedPage, 'settings-server-protection.png', 'settings');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('06-settings-user-management', async ({ authenticatedPage }) => {
|
|
60
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
61
|
+
await nav.goToSettings('user-management');
|
|
62
|
+
|
|
63
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
64
|
+
|
|
65
|
+
await captureFullPage(authenticatedPage, 'settings-user-management.png', 'settings');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('07-settings-account', async ({ authenticatedPage }) => {
|
|
69
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
70
|
+
await nav.goToSettings('account');
|
|
71
|
+
|
|
72
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
73
|
+
|
|
74
|
+
await captureFullPage(authenticatedPage, 'settings-account.png', 'settings');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('08-settings-software-upgrade', async ({ authenticatedPage }) => {
|
|
78
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
79
|
+
await nav.goToSettings('software-upgrade');
|
|
80
|
+
|
|
81
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
82
|
+
|
|
83
|
+
await captureFullPage(authenticatedPage, 'settings-software-upgrade.png', 'settings');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('09-settings-diagnostics', async ({ authenticatedPage }) => {
|
|
87
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
88
|
+
await nav.goToSettings('diagnostics');
|
|
89
|
+
|
|
90
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
91
|
+
|
|
92
|
+
await captureFullPage(authenticatedPage, 'settings-diagnostics.png', 'settings');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('10-settings-experimental', async ({ authenticatedPage }) => {
|
|
96
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
97
|
+
await nav.goToSettings('experimental');
|
|
98
|
+
|
|
99
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
100
|
+
|
|
101
|
+
await captureFullPage(authenticatedPage, 'settings-experimental.png', 'settings');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('11-settings-slicer', async ({ authenticatedPage }) => {
|
|
105
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
106
|
+
await nav.goToSettings('slicer');
|
|
107
|
+
|
|
108
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
109
|
+
|
|
110
|
+
await captureFullPage(authenticatedPage, 'settings-slicer.png', 'settings');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('12-settings-debug-socket', async ({ authenticatedPage }) => {
|
|
114
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
115
|
+
await nav.goToSettings('debug-socket');
|
|
116
|
+
|
|
117
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
118
|
+
|
|
119
|
+
await captureFullPage(authenticatedPage, 'settings-debug-socket.png', 'settings');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('13-settings-about', async ({ authenticatedPage }) => {
|
|
123
|
+
const nav = createNavigationHelper(authenticatedPage);
|
|
124
|
+
await nav.goToSettings('about');
|
|
125
|
+
|
|
126
|
+
await authenticatedPage.waitForTimeout(1000);
|
|
127
|
+
|
|
128
|
+
await captureFullPage(authenticatedPage, 'settings-about.png', 'settings');
|
|
129
|
+
});
|
|
130
|
+
});
|