image-exporter 0.0.1

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.
Files changed (46) hide show
  1. package/.gitattributes +2 -0
  2. package/.prettierrc +5 -0
  3. package/LICENSE.md +201 -0
  4. package/README.md +3 -0
  5. package/dist/image-exporter.es.js +3807 -0
  6. package/dist/image-exporter.umd.js +3813 -0
  7. package/example/example.css +122 -0
  8. package/example/example.html +152 -0
  9. package/example/github.jpg +0 -0
  10. package/example/poll-h.svg +1 -0
  11. package/package.json +50 -0
  12. package/src/capture-images.ts +129 -0
  13. package/src/clean-up.ts +50 -0
  14. package/src/cors-proxy/index.ts +22 -0
  15. package/src/cors-proxy/proxy-css.ts +52 -0
  16. package/src/cors-proxy/proxy-images.ts +90 -0
  17. package/src/default-options.ts +58 -0
  18. package/src/download-images.ts +52 -0
  19. package/src/get-capture-element.test.html +21 -0
  20. package/src/get-capture-element.test.ts +36 -0
  21. package/src/get-capture-element.ts +175 -0
  22. package/src/get-options/get-input-options.test.html +217 -0
  23. package/src/get-options/get-input-options.test.ts +109 -0
  24. package/src/get-options/get-input-options.ts +40 -0
  25. package/src/get-options/get-item-options.ts +46 -0
  26. package/src/get-options/get-wrapper-options.test.html +33 -0
  27. package/src/get-options/get-wrapper-options.test.ts +109 -0
  28. package/src/get-options/get-wrapper-options.ts +84 -0
  29. package/src/get-options/index.ts +28 -0
  30. package/src/image-exporter.ts +108 -0
  31. package/src/index.ts +8 -0
  32. package/src/types/image.ts +2 -0
  33. package/src/types/index.ts +2 -0
  34. package/src/types/options.ts +69 -0
  35. package/src/utils/convert-to-slug.ts +15 -0
  36. package/src/utils/get-attribute-values.ts +68 -0
  37. package/src/utils/get-date-MMDDYY.ts +11 -0
  38. package/src/utils/ignore-items.ts +11 -0
  39. package/src/utils/index.ts +18 -0
  40. package/src/utils/is-valid-url.ts +20 -0
  41. package/src/utils/is-visible.ts +12 -0
  42. package/src/utils/parse-labels.ts +55 -0
  43. package/src/utils/push-to-window.ts +3 -0
  44. package/tests/index.html +88 -0
  45. package/tests/input-tests.html +169 -0
  46. package/vite.config.js +39 -0
@@ -0,0 +1,58 @@
1
+ import * as types from "./types";
2
+
3
+ export const defaultOptions: types.Options = {
4
+ corsProxyBaseUrl: "",
5
+ downloadImages: true,
6
+ selectors: {
7
+ wrapper: "[ie='wrapper']",
8
+ capture: "[ie='capture']",
9
+ trigger: "[ie='trigger']",
10
+ slug: "[ie='slug']",
11
+ ignore: "[ie='ignore']",
12
+ },
13
+ image: {
14
+ scale: {
15
+ value: 1,
16
+ attributeSelector: "ie-scale",
17
+ inputSelector: "ie-scale-input",
18
+ },
19
+ quality: {
20
+ value: 1,
21
+ attributeSelector: "ie-quality",
22
+ inputSelector: "ie-quality-input",
23
+ },
24
+ format: {
25
+ value: "jpg",
26
+ attributeSelector: "ie-format",
27
+ inputSelector: "ie-format-input",
28
+ },
29
+ dateInLabel: {
30
+ value: true,
31
+ attributeSelector: "ie-img-label-date",
32
+ inputSelector: "ie-img-label-date-input",
33
+ },
34
+ scaleInLabel: {
35
+ value: true,
36
+ attributeSelector: "ie-img-label-scale",
37
+ inputSelector: "ie-img-label-scale-input",
38
+ },
39
+ },
40
+ zip: {
41
+ label: {
42
+ value: "images",
43
+ attributeSelector: "ie-zip-label",
44
+ inputSelector: "ie-zip-label-input",
45
+ },
46
+ dateInLabel: {
47
+ value: true,
48
+ attributeSelector: "ie-zip-label-date",
49
+ inputSelector: "ie-zip-label-date-input",
50
+ },
51
+ scaleInLabel: {
52
+ value: true,
53
+ attributeSelector: "ie-zip-label-scale",
54
+ inputSelector: "ie-zip-label-scale-input",
55
+ },
56
+ },
57
+ debug: false,
58
+ };
@@ -0,0 +1,52 @@
1
+ import * as types from "./types";
2
+ import download from "downloadjs";
3
+ import JSZip from "jszip";
4
+ import { parseZipLabel } from "./utils";
5
+
6
+ /**
7
+ * Downloads images based on the provided array of images and options.
8
+ * If there is only one image, it is downloaded individually.
9
+ * If there are multiple images, they are zipped and downloaded as a single file.
10
+ *
11
+ * @param images - An array of images to be downloaded. Each image should be represented as a tuple with the data URL and the file name.
12
+ * @param options - Additional options for downloading the images.
13
+ * @returns A promise that resolves when all the images are downloaded.
14
+ */
15
+ export async function downloadImages(images: types.Image[], options: types.Options) {
16
+ if (images.length === 1) {
17
+ const [dataURL, fileName] = images[0];
18
+
19
+ await download(dataURL, fileName);
20
+ } else if (images.length > 1) {
21
+ const zipName = parseZipLabel(options);
22
+ const zipBlob = await zipUpImages(images);
23
+
24
+ await download(zipBlob, zipName);
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Zips up the given images into a single ZIP file.
30
+ *
31
+ * @param images - An array of image tuples, where each tuple contains the data URL and the filename.
32
+ * @returns A Promise that resolves to the generated ZIP file as a Blob.
33
+ * @throws If there is an error creating the ZIP file.
34
+ */
35
+ async function zipUpImages(images: types.Image[]) {
36
+ const zip = new JSZip();
37
+ // Loop through each image tuple and add to the zip
38
+ images.forEach(([dataURL, filename]) => {
39
+ // Extract the content from the data URL
40
+ const content = dataURL.split(",")[1]; // Assumes base64 encoding
41
+ zip.file(filename, content, { base64: true });
42
+ });
43
+
44
+ try {
45
+ // Generate the ZIP file
46
+ const zipBlob = await zip.generateAsync({ type: "blob" });
47
+ return zipBlob;
48
+ } catch (error) {
49
+ console.error("Error creating ZIP:", error);
50
+ throw error;
51
+ }
52
+ }
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Tests</title>
7
+ </head>
8
+ <body>
9
+ <div ie="wrapper">
10
+ <div ie="capture" ie-scale="1,2,3"></div>
11
+ <div ie="capture"></div>
12
+ <div ie="capture"></div>
13
+ <div ie="capture"></div>
14
+ </div>
15
+ <script src="../../dist/image-exporter.umd.js"></script>
16
+ <script>
17
+ let imageExporter = new ImageExporter({ downloadImages: false, debug: true });
18
+ imageExporter.captureAll();
19
+ </script>
20
+ </body>
21
+ </html>
@@ -0,0 +1,36 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from "vitest";
2
+ import puppeteer from "puppeteer";
3
+ import path from "path";
4
+ import * as types from "./types";
5
+ import { defaultOptions } from "./default-options";
6
+
7
+ describe("get-capture-element", () => {
8
+ let browser;
9
+ let page;
10
+
11
+ beforeAll(async () => {
12
+ // Setup for puppeteer with Vitest
13
+ browser = await puppeteer.launch();
14
+ page = await browser.newPage();
15
+ await page.goto(`file://${path.join(__dirname, "get-capture-element.test.html")}`);
16
+ });
17
+
18
+ afterAll(async () => {
19
+ // Teardown for puppeteer with Vitest
20
+ await browser.close();
21
+ });
22
+
23
+ it("encapsulate multi-scale", async () => {
24
+ const result = await page.evaluate(() => {
25
+ const js = `const options = { downloadImages: false, debug: true };
26
+ const imageExporter = new ImageExporter(options);
27
+ const images = imageExporter.captureAll();`;
28
+ //insert at the end of the body
29
+ const script = document.createElement("script");
30
+ script.text = js;
31
+ document.body.appendChild(script);
32
+
33
+ return (window as any).getInputOptionsDebug;
34
+ });
35
+ });
36
+ });
@@ -0,0 +1,175 @@
1
+ import * as types from "./types";
2
+ import { isVisible } from "./utils/is-visible";
3
+ import { pushToWindow } from "./utils/push-to-window";
4
+
5
+ // Finds all elements to be captured and returns them in an array
6
+ export function getCaptureElements(options: types.Options): HTMLElement[] {
7
+ try {
8
+ if (!document.querySelector(options.selectors.capture)) {
9
+ console.error("ImageExporter: No capture items found in the wrapper.");
10
+ return [];
11
+ }
12
+
13
+ // If CSV values found in scale attribute, encapsulate elements until all scales are accounted for
14
+ findMultiScaleElements(options);
15
+
16
+ // Find all elements to be captured (which includes the multi-scale elements)
17
+ const elements = Array.from(
18
+ document.querySelectorAll(
19
+ `${options.selectors.wrapper} ${options.selectors.capture}`
20
+ ) as NodeListOf<HTMLElement>
21
+ );
22
+
23
+ // Filter out elements that are not visible
24
+ const visibleElements = elements.filter((element) => isVisible(element));
25
+
26
+ return visibleElements;
27
+ } catch (e) {
28
+ console.error("ImageExporter: Error in getCaptureElements", e);
29
+ return [];
30
+ }
31
+ }
32
+
33
+ // If CSV values found in ${prefix}-scale, encapsulate elements until all scales are accounted for
34
+ export function findMultiScaleElements(options: types.Options) {
35
+ try {
36
+ const elements = Array.from(
37
+ document.querySelectorAll(
38
+ `${options.selectors.wrapper} ${options.selectors.capture}`
39
+ ) as NodeListOf<HTMLElement>
40
+ );
41
+ if (elements) {
42
+ const elementsWithScaleAttribute = elements.filter((element) =>
43
+ element.hasAttribute(options.image.scale.attributeSelector)
44
+ );
45
+
46
+ // Check attribute value. It will be a string.
47
+ // If string successfully converts to a number, do nothing.
48
+ // If string is comma-separated, convert to array of numbers.
49
+ elementsWithScaleAttribute.forEach((element) => {
50
+ const scaleValue: any = element.getAttribute(
51
+ options.image.scale.attributeSelector
52
+ );
53
+
54
+ if (scaleValue.includes(",")) {
55
+ console.log("Multi-scale element found:", scaleValue);
56
+ // If scaleValue is an array...
57
+ const scaleArray: Array<Number> = scaleValue.split(",").map(Number);
58
+
59
+ encapsulateMultiScaleElements(options, element, scaleArray, scaleValue);
60
+ if (options.debug)
61
+ pushToWindow("findMultiScaleElementsTest", element.outerHTML);
62
+ }
63
+ });
64
+ return true;
65
+ } else {
66
+ return false;
67
+ }
68
+ } catch (e) {
69
+ console.error("ImageExporter: Error in findMultiScaleElements", e);
70
+ return;
71
+ }
72
+ }
73
+
74
+ function encapsulateMultiScaleElements(
75
+ options: types.Options,
76
+ element: Element,
77
+ scaleArray: Array<Number>,
78
+ scaleValue: string
79
+ ) {
80
+ try {
81
+ // Set scale attribute
82
+ element.setAttribute(options.image.scale.attributeSelector, scaleArray[0].toString());
83
+ // Force include scale img attribute
84
+ element.setAttribute(options.image.scaleInLabel.attributeSelector, "true");
85
+ element.setAttribute("ie-clone-source", scaleValue);
86
+
87
+ // iterate through array and wrap the element in a new element for each scale
88
+ for (let i = 1; i < scaleArray.length; i++) {
89
+ const newElement = cloneElementAttributes(options, element);
90
+ // Set scale attribute
91
+ newElement.setAttribute(
92
+ options.image.scale.attributeSelector,
93
+ scaleArray[i].toString()
94
+ );
95
+ // Force include scale img attribute
96
+ newElement.setAttribute(options.image.scaleInLabel.attributeSelector, "true");
97
+ // Insert element before the original element, then move the original element inside the new element, deleting the original element
98
+ if (element.parentNode) {
99
+ element.parentNode.insertBefore(newElement, element);
100
+ newElement.appendChild(element);
101
+ console.log("Encapsulated element", element, "with scale", scaleArray[i]);
102
+ }
103
+ }
104
+ } catch (e) {
105
+ console.error("ImageExporter: Error in encapsulateMultiScaleElements", e);
106
+ return;
107
+ }
108
+ }
109
+
110
+ // only clones attributes that are in the options.image[key].attributeSelector
111
+ function cloneElementAttributes(
112
+ options: types.Options,
113
+ originalElement: Element
114
+ ): Element {
115
+ try {
116
+ // Create a new div element
117
+ const clonedElement = document.createElement("div");
118
+
119
+ const arrayOfPossibleAttributes = Object.keys(options.image).map(
120
+ (key) => options.image[key].attributeSelector
121
+ );
122
+
123
+ // Adds capture attribute to cloned element
124
+ const { prefix, value } = parseStringAttribute(options.selectors.capture);
125
+ clonedElement.setAttribute(prefix, value);
126
+ clonedElement.setAttribute("ie-clone", "true");
127
+ setExplicitDimensions(originalElement, clonedElement);
128
+
129
+ // Iterate over all attributes of the original element
130
+ Array.from(originalElement.attributes).forEach((attr: any) => {
131
+ // Check if the attribute name exists in types.Attributes
132
+ if (attr.name in arrayOfPossibleAttributes) {
133
+ // Copy the attribute to the cloned element
134
+ clonedElement.setAttribute(attr.name, attr.value);
135
+ }
136
+ });
137
+
138
+ return clonedElement;
139
+ } catch (e) {
140
+ console.error("ImageExporter: Error in cloneElementAttributes", e);
141
+ return originalElement;
142
+ }
143
+ }
144
+
145
+ function parseStringAttribute(attributeValue: string) {
146
+ if (!attributeValue.includes("=")) {
147
+ throw new Error("Invalid attribute format. Expected format: [prefix=value]");
148
+ }
149
+
150
+ const attributeArray = attributeValue.split("=");
151
+ if (attributeArray.length !== 2) {
152
+ throw new Error("Invalid attribute format. Expected format: [prefix=value]");
153
+ }
154
+
155
+ const prefix = attributeArray[0].trim().replace(/^\[|\]$/g, "");
156
+ const value = attributeArray[1]
157
+ .trim()
158
+ .replace(/^\[|\]$/g, "")
159
+ .replace(/^'|'$/g, "");
160
+
161
+ if (!prefix || !value) {
162
+ throw new Error("Invalid attribute format. Prefix or value is missing.");
163
+ }
164
+
165
+ return { prefix, value };
166
+ }
167
+
168
+ function setExplicitDimensions(originalElement: any, clonedElement: any) {
169
+ const originalElementStyle = window.getComputedStyle(originalElement);
170
+ const originalElementWidth = originalElementStyle.getPropertyValue("width");
171
+ const originalElementHeight = originalElementStyle.getPropertyValue("height");
172
+
173
+ clonedElement.style.width = originalElementWidth;
174
+ clonedElement.style.height = originalElementHeight;
175
+ }
@@ -0,0 +1,217 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Tests</title>
7
+ </head>
8
+ <body>
9
+ <section>
10
+ <div>
11
+ <!-- Scale -->
12
+ <label for="scale"><strong>Scale</strong></label>
13
+ <select title="scale" ie-scale-input>
14
+ <option value="5">@1x</option>
15
+ </select>
16
+ </div>
17
+ <div>
18
+ <!-- Quality -->
19
+ <label for="quality"><strong>Quality</strong></label>
20
+ <input
21
+ type="range"
22
+ id="quality"
23
+ name="quality"
24
+ min="0.00"
25
+ max="1.00"
26
+ value="0.75"
27
+ step="0.01"
28
+ ie-quality-input
29
+ />
30
+ </div>
31
+ <div>
32
+ <!-- Format -->
33
+ <label for="format"><strong>Format</strong></label>
34
+ <select title="format" ie-format-input>
35
+ <option value="jpg">JPG</option>
36
+ </select>
37
+ </div>
38
+ <div>
39
+ <fieldset>
40
+ <legend><strong>Image label</strong></legend>
41
+ <!-- dateInLabel -->
42
+ <label for="dateInLabel">
43
+ <input
44
+ type="checkbox"
45
+ id="dateInLabel"
46
+ name="dateInLabel"
47
+ name="dateInLabel"
48
+ role="switch"
49
+ checked="checked"
50
+ ie-img-label-date-input
51
+ />
52
+ Date in label
53
+ </label>
54
+ <!--scaleInLabel-->
55
+ <label for="scaleInLabel">
56
+ <input
57
+ type="checkbox"
58
+ id="scaleInLabel"
59
+ name="scaleInLabel"
60
+ name="scaleInLabel"
61
+ role="switch"
62
+ checked="checked"
63
+ ie-img-label-scale-input
64
+ />
65
+ Scale in label
66
+ </label>
67
+ </fieldset>
68
+ </div>
69
+ <fieldset>
70
+ <legend><strong>Zip label</strong></legend>
71
+ <!-- zipLabel -->
72
+ <label for="zipLabel">Label</label>
73
+ <input type="text" id="zipLabel" name="zipLabel" ie-zip-label-input value="ie" />
74
+ <!-- zipDateInLabel -->
75
+ <label for="zipDateInLabel">
76
+ <input
77
+ type="checkbox"
78
+ id="zipDateInLabel"
79
+ name="zipDateInLabel"
80
+ name="zipDateInLabel"
81
+ role="switch"
82
+ checked="checked"
83
+ ie-zip-label-date-input
84
+ />
85
+ Date in label
86
+ </label>
87
+ <!--zipScaleInLabel-->
88
+ <label for="zipScaleInLabel">
89
+ <input
90
+ type="checkbox"
91
+ id="zipScaleInLabel"
92
+ name="zipScaleInLabel"
93
+ name="zipScaleInLabel"
94
+ role="switch"
95
+ checked="checked"
96
+ ie-zip-label-scale-input
97
+ />
98
+ Scale in label
99
+ </label>
100
+ </fieldset>
101
+
102
+ <button ie-trigger>Run</button>
103
+ </section>
104
+ <section>
105
+ <div>
106
+ <!-- Scale -->
107
+ <label for="test-scale"><strong>Scale</strong></label>
108
+ <select title="test-scale" test-scale-input>
109
+ <option value="5">@1x</option>
110
+ </select>
111
+ </div>
112
+ <div>
113
+ <!-- Quality -->
114
+ <label for="quality"><strong>Quality</strong></label>
115
+ <input
116
+ type="range"
117
+ id="quality"
118
+ name="quality"
119
+ min="0.00"
120
+ max="1.00"
121
+ value="0.75"
122
+ step="0.01"
123
+ test-quality-input
124
+ />
125
+ </div>
126
+ <div>
127
+ <!-- Format -->
128
+ <label for="format"><strong>Format</strong></label>
129
+ <select title="format" test-format-input>
130
+ <option value="jpg">JPG</option>
131
+ </select>
132
+ </div>
133
+ <div>
134
+ <fieldset>
135
+ <legend><strong>Image label</strong></legend>
136
+ <!-- dateInLabel -->
137
+ <label for="dateInLabel">
138
+ <input
139
+ type="checkbox"
140
+ id="dateInLabel"
141
+ name="dateInLabel"
142
+ name="dateInLabel"
143
+ role="switch"
144
+ checked="checked"
145
+ test-img-label-date-input
146
+ />
147
+ Date in label
148
+ </label>
149
+ <!--scaleInLabel-->
150
+ <label for="scaleInLabel">
151
+ <input
152
+ type="checkbox"
153
+ id="scaleInLabel"
154
+ name="scaleInLabel"
155
+ name="scaleInLabel"
156
+ role="switch"
157
+ checked="checked"
158
+ test-img-label-scale-input
159
+ />
160
+ Scale in label
161
+ </label>
162
+ </fieldset>
163
+ </div>
164
+ <fieldset>
165
+ <legend><strong>Zip label</strong></legend>
166
+ <!-- zipLabel -->
167
+ <label for="zipLabel">Label</label>
168
+ <input
169
+ type="text"
170
+ id="zipLabel"
171
+ name="zipLabel"
172
+ test-zip-label-input
173
+ value="ie"
174
+ />
175
+ <!-- zipDateInLabel -->
176
+ <label for="zipDateInLabel">
177
+ <input
178
+ type="checkbox"
179
+ id="zipDateInLabel"
180
+ name="zipDateInLabel"
181
+ name="zipDateInLabel"
182
+ role="switch"
183
+ checked="checked"
184
+ test-zip-label-date-input
185
+ />
186
+ Date in label
187
+ </label>
188
+ <!--zipScaleInLabel-->
189
+ <label for="zipScaleInLabel">
190
+ <input
191
+ type="checkbox"
192
+ id="zipScaleInLabel"
193
+ name="zipScaleInLabel"
194
+ name="zipScaleInLabel"
195
+ role="switch"
196
+ checked="checked"
197
+ test-zip-label-scale-input
198
+ />
199
+ Scale in label
200
+ </label>
201
+ </fieldset>
202
+ </section>
203
+ <div
204
+ ie="wrapper"
205
+ ie-scale="2"
206
+ ie-quality="0.55"
207
+ ie-format="png"
208
+ ie-img-label-date="false"
209
+ ie-img-label-scale="false"
210
+ ie-zip-label="yay"
211
+ ie-zip-label-date="false"
212
+ ie-zip-label-scale="false"
213
+ ></div>
214
+ <div test="wrapper"></div>
215
+ <script src="../../dist/image-exporter.umd.js"></script>
216
+ </body>
217
+ </html>
@@ -0,0 +1,109 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from "vitest";
2
+ import puppeteer from "puppeteer";
3
+ import path from "path";
4
+ import * as types from "../types";
5
+ import { defaultOptions } from "../default-options";
6
+
7
+ describe("get-input-options", () => {
8
+ let browser;
9
+ let page;
10
+
11
+ beforeAll(async () => {
12
+ // Setup for puppeteer with Vitest
13
+ browser = await puppeteer.launch();
14
+ page = await browser.newPage();
15
+ await page.goto(`file://${path.join(__dirname, "get-input-options.test.html")}`);
16
+ });
17
+
18
+ afterAll(async () => {
19
+ // Teardown for puppeteer with Vitest
20
+ await browser.close();
21
+ });
22
+
23
+ it("standard attributes", async () => {
24
+ const result = await page.evaluate(() => {
25
+ const js = `const options = { downloadImages: false, debug: true };
26
+ const imageExporter = new ImageExporter(options);
27
+ const images = imageExporter.captureAll();`;
28
+ //insert at the end of the body
29
+ const script = document.createElement("script");
30
+ script.text = js;
31
+ document.body.appendChild(script);
32
+
33
+ return (window as any).getInputOptionsDebug;
34
+ });
35
+
36
+ // Assertions can then be made based on the result object
37
+ expect(result.image.scale.value).toBe(5);
38
+ expect(result.image.quality.value).toBe(0.75);
39
+ expect(result.image.format.value).toBe("jpg");
40
+ expect(result.image.dateInLabel.value).toBe(true);
41
+ expect(result.image.scaleInLabel.value).toBe(true);
42
+ expect(result.zip.label.value).toBe("ie");
43
+ expect(result.zip.dateInLabel.value).toBe(true);
44
+ expect(result.zip.scaleInLabel.value).toBe(true);
45
+ });
46
+
47
+ it("custom attributes", async () => {
48
+ await page.reload();
49
+ const result = await page.evaluate(() => {
50
+ const js = `const options = {
51
+ downloadImages: false,
52
+ selectors: {
53
+ wrapper: "[test='wrapper']",
54
+ capture: "[test='capture']",
55
+ trigger: "[test='trigger']",
56
+ slug: "[test='slug']",
57
+ ignore: "[test='ignore']",
58
+ },
59
+ image: {
60
+ scale: {
61
+ inputSelector: "test-scale-input",
62
+ },
63
+ quality: {
64
+ inputSelector: "test-quality-input",
65
+ },
66
+ format: {
67
+ inputSelector: "test-format-input",
68
+ },
69
+ dateInLabel: {
70
+ inputSelector: "test-img-label-date-input",
71
+ },
72
+ scaleInLabel: {
73
+ inputSelector: "test-img-label-scale-input",
74
+ },
75
+ },
76
+ zip: {
77
+ label: {
78
+ inputSelector: "test-zip-label-input",
79
+ },
80
+ dateInLabel: {
81
+ inputSelector: "test-zip-label-date-input",
82
+ },
83
+ scaleInLabel: {
84
+ inputSelector: "test-zip-label-scale-input",
85
+ },
86
+ },
87
+ debug: true,
88
+ };
89
+ const imageExporter = new ImageExporter(options);
90
+ const images = imageExporter.captureAll();`;
91
+ //insert at the end of the body
92
+ const script = document.createElement("script");
93
+ script.text = js;
94
+ document.body.appendChild(script);
95
+
96
+ return (window as any).getInputOptionsDebug;
97
+ });
98
+
99
+ // Assertions can then be made based on the result object
100
+ expect(result.image.scale.value).toBe(5);
101
+ expect(result.image.quality.value).toBe(0.75);
102
+ expect(result.image.format.value).toBe("jpg");
103
+ expect(result.image.dateInLabel.value).toBe(true);
104
+ expect(result.image.scaleInLabel.value).toBe(true);
105
+ expect(result.zip.label.value).toBe("ie");
106
+ expect(result.zip.dateInLabel.value).toBe(true);
107
+ expect(result.zip.scaleInLabel.value).toBe(true);
108
+ });
109
+ });