pdfdancer-client-typescript 1.0.16 → 1.0.18
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/README.md +12 -4
- package/dist/__tests__/e2e/pdf-assertions.d.ts.map +1 -1
- package/dist/__tests__/e2e/pdf-assertions.js +1 -1
- package/dist/__tests__/e2e/pdf-assertions.js.map +1 -1
- package/dist/__tests__/e2e/test-drawing-helpers.d.ts +148 -0
- package/dist/__tests__/e2e/test-drawing-helpers.d.ts.map +1 -0
- package/dist/__tests__/e2e/test-drawing-helpers.js +343 -0
- package/dist/__tests__/e2e/test-drawing-helpers.js.map +1 -0
- package/dist/__tests__/e2e/test-helpers.d.ts +10 -0
- package/dist/__tests__/e2e/test-helpers.d.ts.map +1 -1
- package/dist/__tests__/e2e/test-helpers.js +55 -0
- package/dist/__tests__/e2e/test-helpers.js.map +1 -1
- package/dist/image-builder.d.ts +1 -0
- package/dist/image-builder.d.ts.map +1 -1
- package/dist/image-builder.js +4 -0
- package/dist/image-builder.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +54 -2
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +115 -1
- package/dist/models.js.map +1 -1
- package/dist/path-builder.d.ts +110 -0
- package/dist/path-builder.d.ts.map +1 -0
- package/dist/path-builder.js +191 -0
- package/dist/path-builder.js.map +1 -0
- package/dist/pdfdancer_v1.d.ts +7 -0
- package/dist/pdfdancer_v1.d.ts.map +1 -1
- package/dist/pdfdancer_v1.js +72 -2
- package/dist/pdfdancer_v1.js.map +1 -1
- package/package.json +18 -2
- package/.claude/commands/discuss.md +0 -4
- package/.eslintrc.js +0 -27
- package/.github/workflows/ci.yml +0 -86
- package/.github/workflows/daily-tests.yml +0 -54
- package/NOTICE +0 -8
- package/docs/openapi.yml +0 -2640
- package/fixtures/DancingScript-Regular.ttf +0 -0
- package/fixtures/Empty.pdf +0 -0
- package/fixtures/JetBrainsMono-Regular.ttf +0 -0
- package/fixtures/ObviouslyAwesome.pdf +0 -0
- package/fixtures/README.md +0 -23
- package/fixtures/Showcase.pdf +0 -0
- package/fixtures/basic-paths.pdf +0 -0
- package/fixtures/form-xobject-example.pdf +0 -0
- package/fixtures/logo-80.png +0 -0
- package/fixtures/mixed-form-types.pdf +0 -0
- package/jest.config.js +0 -27
- package/scripts/release.js +0 -91
- package/scripts/test-release.js +0 -59
- package/src/__tests__/assertions.ts +0 -12
- package/src/__tests__/client-v1.test.ts +0 -70
- package/src/__tests__/e2e/acroform.test.ts +0 -166
- package/src/__tests__/e2e/context-manager-showcase.test.ts +0 -267
- package/src/__tests__/e2e/create-new.test.ts +0 -133
- package/src/__tests__/e2e/form_x_object.test.ts +0 -87
- package/src/__tests__/e2e/image-showcase.test.ts +0 -133
- package/src/__tests__/e2e/image.test.ts +0 -147
- package/src/__tests__/e2e/line-showcase.test.ts +0 -113
- package/src/__tests__/e2e/line.test.ts +0 -187
- package/src/__tests__/e2e/page-showcase.test.ts +0 -154
- package/src/__tests__/e2e/page.test.ts +0 -47
- package/src/__tests__/e2e/paragraph-showcase.test.ts +0 -515
- package/src/__tests__/e2e/paragraph.test.ts +0 -681
- package/src/__tests__/e2e/path.test.ts +0 -108
- package/src/__tests__/e2e/pdf-assertions.ts +0 -248
- package/src/__tests__/e2e/pdfdancer-showcase.test.ts +0 -40
- package/src/__tests__/e2e/snapshot-showcase.test.ts +0 -158
- package/src/__tests__/e2e/snapshot.test.ts +0 -296
- package/src/__tests__/e2e/test-helpers.ts +0 -152
- package/src/__tests__/e2e/token_from_env.test.ts +0 -80
- package/src/__tests__/fingerprint.test.ts +0 -36
- package/src/__tests__/retry-mechanism.test.ts +0 -642
- package/src/__tests__/standard-fonts.test.ts +0 -87
- package/src/__tests__/url-builder.test.ts +0 -44
- package/src/exceptions.ts +0 -63
- package/src/fingerprint.ts +0 -182
- package/src/image-builder.ts +0 -59
- package/src/index.ts +0 -49
- package/src/models.ts +0 -1051
- package/src/page-builder.ts +0 -130
- package/src/paragraph-builder.ts +0 -644
- package/src/pdfdancer_v1.ts +0 -2283
- package/src/types.ts +0 -407
- package/tsconfig.json +0 -20
- package/update-api-spec.sh +0 -3
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import {Color, PDFDancer, StandardFonts} from '../../index';
|
|
2
|
-
import {requireEnvAndFixture} from './test-helpers';
|
|
3
|
-
import {PDFAssertions} from './pdf-assertions';
|
|
4
|
-
|
|
5
|
-
const SAMPLE_PARAGRAPH = 'This is regular Sans text showing alignment and styles.';
|
|
6
|
-
|
|
7
|
-
describe('Paragraph Edit Session E2E Tests (Showcase)', () => {
|
|
8
|
-
test('basic usage', async () => {
|
|
9
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
10
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
11
|
-
|
|
12
|
-
const paragraphs = await pdf.selectParagraphs();
|
|
13
|
-
expect(paragraphs.length).toBe(24);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test('edit text only', async () => {
|
|
17
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
18
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
19
|
-
|
|
20
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
21
|
-
await paragraph.edit().replace('This is replaced\ntext on two lines').apply();
|
|
22
|
-
|
|
23
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
24
|
-
await assertions.assertTextlineExists('This is replaced', 0);
|
|
25
|
-
await assertions.assertTextlineExists('text on two lines', 0);
|
|
26
|
-
await assertions.assertTextlineDoesNotExist(SAMPLE_PARAGRAPH, 0);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test('edit font only', async () => {
|
|
30
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
31
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
32
|
-
|
|
33
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
34
|
-
await paragraph.edit().font('Helvetica', 28).apply();
|
|
35
|
-
|
|
36
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
37
|
-
await assertions.assertTextlineHasFont(SAMPLE_PARAGRAPH, 'Helvetica', 28);
|
|
38
|
-
await assertions.assertTextlineHasColor(SAMPLE_PARAGRAPH, new Color(0, 0, 0));
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('edit text and font', async () => {
|
|
42
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
43
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
44
|
-
|
|
45
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
46
|
-
await paragraph.edit().replace('New Text\nHere').font('Helvetica', 16).apply();
|
|
47
|
-
|
|
48
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
49
|
-
await assertions.assertTextlineHasFont('New Text', 'Helvetica', 16);
|
|
50
|
-
await assertions.assertTextlineHasFont('Here', 'Helvetica', 16);
|
|
51
|
-
await assertions.assertTextlineDoesNotExist(SAMPLE_PARAGRAPH);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('edit all properties', async () => {
|
|
55
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
56
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
57
|
-
|
|
58
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
59
|
-
await paragraph.edit()
|
|
60
|
-
.replace('Fully\nModified')
|
|
61
|
-
.font('Helvetica', 18)
|
|
62
|
-
.color(new Color(255, 0, 0))
|
|
63
|
-
.lineSpacing(1.5)
|
|
64
|
-
.moveTo(100, 200)
|
|
65
|
-
.apply();
|
|
66
|
-
|
|
67
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
68
|
-
await assertions.assertTextlineHasFont('Fully', 'Helvetica', 18);
|
|
69
|
-
await assertions.assertTextlineHasFont('Modified', 'Helvetica', 18);
|
|
70
|
-
await assertions.assertTextlineHasColor('Fully', new Color(255, 0, 0));
|
|
71
|
-
await assertions.assertTextlineHasColor('Modified', new Color(255, 0, 0));
|
|
72
|
-
await assertions.assertParagraphIsAt('Fully', 100, 200, 0);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test('edit color only', async () => {
|
|
76
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
77
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
78
|
-
|
|
79
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
80
|
-
await paragraph.edit().color(new Color(0, 255, 0)).apply();
|
|
81
|
-
|
|
82
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
83
|
-
await assertions.assertTextlineHasColor(SAMPLE_PARAGRAPH, new Color(0, 255, 0));
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test('edit line spacing only', async () => {
|
|
87
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
88
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
89
|
-
|
|
90
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
91
|
-
await paragraph.edit().lineSpacing(2.0).apply();
|
|
92
|
-
|
|
93
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
94
|
-
await assertions.assertTextlineExists(SAMPLE_PARAGRAPH);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test('edit move only', async () => {
|
|
98
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
99
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
100
|
-
|
|
101
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
102
|
-
await paragraph.edit().moveTo(150, 300).apply();
|
|
103
|
-
|
|
104
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
105
|
-
await assertions.assertTextlineHasFont(SAMPLE_PARAGRAPH, 'AAAZPH+Roboto-Regular', 12);
|
|
106
|
-
await assertions.assertParagraphIsAt(SAMPLE_PARAGRAPH, 150, 300, 0, 0.22);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test('multiple edits sequential', async () => {
|
|
110
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
111
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
112
|
-
|
|
113
|
-
const [first] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
114
|
-
await first.edit().replace('First Edit').apply();
|
|
115
|
-
|
|
116
|
-
const [second] = await pdf.page(0).selectParagraphsStartingWith('First Edit');
|
|
117
|
-
await second.edit().replace('Second Edit').font('Helvetica', 20).apply();
|
|
118
|
-
|
|
119
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
120
|
-
await assertions.assertTextlineHasFont('Second Edit', 'Helvetica', 20);
|
|
121
|
-
await assertions.assertTextlineDoesNotExist('First Edit');
|
|
122
|
-
await assertions.assertTextlineDoesNotExist(SAMPLE_PARAGRAPH);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test('edit multiple paragraphs', async () => {
|
|
126
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
127
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
128
|
-
|
|
129
|
-
const paragraphs = await pdf.page(0).selectParagraphs();
|
|
130
|
-
await paragraphs[0].edit().replace('Modified First').font('Helvetica', 14).apply();
|
|
131
|
-
await paragraphs[1].edit().replace('Modified Second').font('Helvetica', 14).apply();
|
|
132
|
-
|
|
133
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
134
|
-
await assertions.assertTextlineHasFont('Modified First', 'Helvetica', 14);
|
|
135
|
-
await assertions.assertTextlineHasFont('Modified Second', 'Helvetica', 14);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('edit with exception does not apply', async () => {
|
|
139
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
140
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
141
|
-
|
|
142
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
143
|
-
const editor = paragraph.edit();
|
|
144
|
-
editor.replace('Should Fail');
|
|
145
|
-
|
|
146
|
-
await expect(async () => {
|
|
147
|
-
throw new Error('boom');
|
|
148
|
-
}).rejects.toThrow('boom');
|
|
149
|
-
|
|
150
|
-
const remaining = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
151
|
-
expect(remaining.length).toBeGreaterThan(0);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
test('nested PDF and edit sessions', async () => {
|
|
155
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
156
|
-
const pdf1 = await PDFDancer.open(pdfData, token, baseUrl);
|
|
157
|
-
const pdf2 = await PDFDancer.new({initialPageCount: 1}, token, baseUrl);
|
|
158
|
-
|
|
159
|
-
await pdf2.page(0).newParagraph()
|
|
160
|
-
.text('Temporary Text')
|
|
161
|
-
.font(StandardFonts.HELVETICA, 12)
|
|
162
|
-
.at(50, 50)
|
|
163
|
-
.apply();
|
|
164
|
-
|
|
165
|
-
const [paragraph] = await pdf1.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
166
|
-
await paragraph.edit().replace('Nested Edit').apply();
|
|
167
|
-
|
|
168
|
-
const assertions = await PDFAssertions.create(pdf1);
|
|
169
|
-
await assertions.assertTextlineExists('Nested Edit');
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
test('edit preserves position when not specified', async () => {
|
|
173
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
174
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
175
|
-
|
|
176
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
177
|
-
const original = paragraph.position;
|
|
178
|
-
await paragraph.edit().replace('No Move').apply();
|
|
179
|
-
|
|
180
|
-
const [updated] = await pdf.page(0).selectParagraphsStartingWith('No Move');
|
|
181
|
-
expect(updated.position.getX()).toBeCloseTo(original.getX()!, 5);
|
|
182
|
-
expect(updated.position.getY()).toBeCloseTo(original.getY()!, 5);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test('edit chaining', async () => {
|
|
186
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
187
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
188
|
-
|
|
189
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
190
|
-
await paragraph.edit()
|
|
191
|
-
.replace('Chained\nEdits')
|
|
192
|
-
.font('Helvetica', 15)
|
|
193
|
-
.color(new Color(128, 128, 128))
|
|
194
|
-
.lineSpacing(1.8)
|
|
195
|
-
.apply();
|
|
196
|
-
|
|
197
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
198
|
-
await assertions.assertTextlineHasFont('Chained', 'Helvetica', 15);
|
|
199
|
-
await assertions.assertTextlineHasFont('Edits', 'Helvetica', 15);
|
|
200
|
-
await assertions.assertTextlineHasColor('Chained', new Color(128, 128, 128));
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test('edit with standard fonts', async () => {
|
|
204
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
205
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
206
|
-
|
|
207
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
208
|
-
await paragraph.edit().replace('Times Roman').font(StandardFonts.TIMES_ROMAN, 18).apply();
|
|
209
|
-
|
|
210
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
211
|
-
await assertions.assertTextlineHasFont('Times Roman', StandardFonts.TIMES_ROMAN, 18);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
test('edit with multiline text', async () => {
|
|
215
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
216
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
217
|
-
|
|
218
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
219
|
-
await paragraph.edit().replace('Line 1\nLine 2').font('Helvetica', 12).apply();
|
|
220
|
-
|
|
221
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
222
|
-
await assertions.assertTextlineExists('Line 1');
|
|
223
|
-
await assertions.assertTextlineExists('Line 2');
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
test('edit with empty text', async () => {
|
|
227
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
228
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
229
|
-
|
|
230
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
231
|
-
await paragraph.edit().replace('').font('Helvetica', 12).apply();
|
|
232
|
-
|
|
233
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
234
|
-
await assertions.assertTextlineDoesNotExist(SAMPLE_PARAGRAPH);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
test('example from docs', async () => {
|
|
238
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
239
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
240
|
-
|
|
241
|
-
const [paragraph] = await pdf.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
242
|
-
await paragraph.edit().replace('Awesomely\nObvious!').font('Helvetica', 12).apply();
|
|
243
|
-
|
|
244
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
245
|
-
await assertions.assertTextlineHasFont('Awesomely', 'Helvetica', 12);
|
|
246
|
-
await assertions.assertTextlineHasFont('Obvious!', 'Helvetica', 12);
|
|
247
|
-
await assertions.assertTextlineDoesNotExist(SAMPLE_PARAGRAPH);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
test('vs manual apply', async () => {
|
|
251
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
252
|
-
const pdf1 = await PDFDancer.open(pdfData, token, baseUrl);
|
|
253
|
-
|
|
254
|
-
const [paragraph1] = await pdf1.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
255
|
-
await paragraph1.edit().replace('Test Text').font('Helvetica', 14).color(new Color(255, 0, 0)).apply();
|
|
256
|
-
|
|
257
|
-
const assertions1 = await PDFAssertions.create(pdf1);
|
|
258
|
-
await assertions1.assertTextlineHasFont('Test Text', 'Helvetica', 14);
|
|
259
|
-
|
|
260
|
-
const pdf2 = await PDFDancer.open(pdfData, token, baseUrl);
|
|
261
|
-
const [paragraph2] = await pdf2.page(0).selectParagraphsStartingWith(SAMPLE_PARAGRAPH);
|
|
262
|
-
await paragraph2.edit().replace('Test Text').font('Helvetica', 14).color(new Color(255, 0, 0)).apply();
|
|
263
|
-
|
|
264
|
-
const assertions2 = await PDFAssertions.create(pdf2);
|
|
265
|
-
await assertions2.assertTextlineHasFont('Test Text', 'Helvetica', 14);
|
|
266
|
-
});
|
|
267
|
-
});
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E2E tests for creating new PDF documents
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {Color, Orientation, PDFDancer, StandardFonts} from '../../index';
|
|
6
|
-
import {getBaseUrl, readToken, serverUp} from './test-helpers';
|
|
7
|
-
import {expectWithin} from '../assertions';
|
|
8
|
-
import {PDFAssertions} from './pdf-assertions';
|
|
9
|
-
|
|
10
|
-
describe('Create New PDF E2E Tests', () => {
|
|
11
|
-
let baseUrl: string;
|
|
12
|
-
let token: string;
|
|
13
|
-
|
|
14
|
-
beforeAll(async () => {
|
|
15
|
-
baseUrl = getBaseUrl();
|
|
16
|
-
const tokenValue = readToken();
|
|
17
|
-
|
|
18
|
-
if (!await serverUp(baseUrl)) {
|
|
19
|
-
throw new Error(`PDFDancer server not reachable at ${baseUrl}; set PDFDANCER_BASE_URL or start server`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!tokenValue) {
|
|
23
|
-
throw new Error('PDFDANCER_TOKEN not set and no token file found; set env or place jwt-token-*.txt in repo');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
token = tokenValue;
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const expectPdfSignature = (bytes: Uint8Array) => {
|
|
30
|
-
expect(bytes.length).toBeGreaterThan(4);
|
|
31
|
-
const signature = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
|
|
32
|
-
expect(signature).toBe('%PDF');
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
test('create new PDF with defaults', async () => {
|
|
36
|
-
const client = await PDFDancer.new(undefined, token, baseUrl);
|
|
37
|
-
|
|
38
|
-
const pages = await client.pages();
|
|
39
|
-
expect(pages).toHaveLength(1);
|
|
40
|
-
|
|
41
|
-
const bytes = await client.getBytes();
|
|
42
|
-
expectPdfSignature(bytes);
|
|
43
|
-
|
|
44
|
-
const assertions = await PDFAssertions.create(client);
|
|
45
|
-
await assertions.assertTotalNumberOfElements(0);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test('create new PDF with custom params', async () => {
|
|
49
|
-
const client = await PDFDancer.new(
|
|
50
|
-
{
|
|
51
|
-
pageSize: 'A4',
|
|
52
|
-
orientation: Orientation.LANDSCAPE,
|
|
53
|
-
initialPageCount: 3
|
|
54
|
-
},
|
|
55
|
-
token,
|
|
56
|
-
baseUrl
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
const pages = await client.pages();
|
|
60
|
-
expect(pages).toHaveLength(3);
|
|
61
|
-
|
|
62
|
-
const assertions = await PDFAssertions.create(client);
|
|
63
|
-
await assertions.assertTotalNumberOfElements(0);
|
|
64
|
-
await assertions.assertPageCount(3);
|
|
65
|
-
for (let index = 0; index < pages.length; index++) {
|
|
66
|
-
await assertions.assertPageDimension(842.0, 595.0, undefined, index);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test('create new PDF with string params', async () => {
|
|
71
|
-
const client = await PDFDancer.new(
|
|
72
|
-
{
|
|
73
|
-
pageSize: 'LETTER',
|
|
74
|
-
orientation: Orientation.PORTRAIT,
|
|
75
|
-
initialPageCount: 2
|
|
76
|
-
},
|
|
77
|
-
token,
|
|
78
|
-
baseUrl
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
const pages = await client.pages();
|
|
82
|
-
expect(pages).toHaveLength(2);
|
|
83
|
-
|
|
84
|
-
const assertions = await PDFAssertions.create(client);
|
|
85
|
-
await assertions.assertTotalNumberOfElements(0);
|
|
86
|
-
await assertions.assertPageCount(2);
|
|
87
|
-
for (let index = 0; index < pages.length; index++) {
|
|
88
|
-
await assertions.assertPageDimension(612.0, 792.0, Orientation.PORTRAIT, index);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test('create new PDF add content and verify placement', async () => {
|
|
93
|
-
const client = await PDFDancer.new(undefined, token, baseUrl);
|
|
94
|
-
|
|
95
|
-
await client.page(0)
|
|
96
|
-
.newParagraph()
|
|
97
|
-
.text('Hello from blank PDF')
|
|
98
|
-
.font(StandardFonts.COURIER_BOLD_OBLIQUE, 9)
|
|
99
|
-
.color(new Color(0, 255, 0))
|
|
100
|
-
.at(100, 201.5)
|
|
101
|
-
.apply();
|
|
102
|
-
|
|
103
|
-
const paragraphs = await client.selectParagraphs();
|
|
104
|
-
expect(paragraphs).toHaveLength(1);
|
|
105
|
-
const paragraph = paragraphs[0];
|
|
106
|
-
expect(paragraph.getText()).toContain('Hello from blank PDF');
|
|
107
|
-
expect(paragraph.getFontName()).toBe(StandardFonts.COURIER_BOLD_OBLIQUE);
|
|
108
|
-
expectWithin(paragraph.getFontSize(), 9, 1e-6);
|
|
109
|
-
expect(paragraph.getColor()).toEqual(new Color(0, 255, 0));
|
|
110
|
-
|
|
111
|
-
expectWithin(paragraph.position.getX()!, 100, 1e-6);
|
|
112
|
-
expectWithin(paragraph.position.getY()!, 201.5, 1e-6);
|
|
113
|
-
|
|
114
|
-
const textLines = await (await client.pages())[0].selectTextLines();
|
|
115
|
-
expect(textLines).toHaveLength(1);
|
|
116
|
-
expect(textLines[0].getText()).toContain('Hello from blank PDF');
|
|
117
|
-
|
|
118
|
-
const assertions = await PDFAssertions.create(client);
|
|
119
|
-
await assertions.assertPageCount(1);
|
|
120
|
-
await assertions.assertTotalNumberOfElements(2);
|
|
121
|
-
await assertions.assertParagraphIsAt('Hello from blank PDF', 100, 201.5);
|
|
122
|
-
await assertions.assertTextHasFont('Hello from blank PDF', StandardFonts.COURIER_BOLD_OBLIQUE, 9);
|
|
123
|
-
await assertions.assertTextHasColor('Hello from blank PDF', new Color(0, 255, 0));
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test('create new PDF rejects invalid page count', async () => {
|
|
127
|
-
await expect(PDFDancer.new(
|
|
128
|
-
{initialPageCount: 0},
|
|
129
|
-
token,
|
|
130
|
-
baseUrl
|
|
131
|
-
)).rejects.toThrow('Initial page count must be at least 1');
|
|
132
|
-
});
|
|
133
|
-
});
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* E2E tests for form operations — new PDFDancer API
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as fs from 'fs';
|
|
6
|
-
import {PDFDancer} from '../../index';
|
|
7
|
-
import {createTempPath, requireEnvAndFixture} from './test-helpers';
|
|
8
|
-
import {PDFAssertions} from './pdf-assertions';
|
|
9
|
-
|
|
10
|
-
describe('Form E2E Tests (v2 API)', () => {
|
|
11
|
-
|
|
12
|
-
test('delete forms', async () => {
|
|
13
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('form-xobject-example.pdf');
|
|
14
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
15
|
-
|
|
16
|
-
const forms = await pdf.selectForms();
|
|
17
|
-
expect(forms).toHaveLength(17);
|
|
18
|
-
expect(forms[0].type).toBe('FORM_X_OBJECT');
|
|
19
|
-
|
|
20
|
-
// Delete all forms directly through their reference
|
|
21
|
-
for (const form of forms) {
|
|
22
|
-
await form.delete();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const remaining = await pdf.selectForms();
|
|
26
|
-
expect(remaining).toHaveLength(0);
|
|
27
|
-
|
|
28
|
-
// Save PDF to verify operation
|
|
29
|
-
const outPath = createTempPath('forms-after-delete.pdf');
|
|
30
|
-
await pdf.save(outPath);
|
|
31
|
-
expect(fs.existsSync(outPath)).toBe(true);
|
|
32
|
-
expect(fs.statSync(outPath).size).toBeGreaterThan(0);
|
|
33
|
-
|
|
34
|
-
// Cleanup
|
|
35
|
-
fs.unlinkSync(outPath);
|
|
36
|
-
|
|
37
|
-
// No additional assertions beyond the direct API checks to avoid
|
|
38
|
-
// relying on backend enumerations that may omit form XObjects in the
|
|
39
|
-
// reopened document.
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('find form by position', async () => {
|
|
43
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('form-xobject-example.pdf');
|
|
44
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
45
|
-
|
|
46
|
-
// Page 0, position (0,0) — expect no forms
|
|
47
|
-
let forms = await pdf.page(0).selectFormsAt(0, 0);
|
|
48
|
-
expect(forms).toHaveLength(0);
|
|
49
|
-
|
|
50
|
-
// Page 0, position (321,601) — expect a form
|
|
51
|
-
forms = await pdf.page(0).selectFormsAt(321, 601, 1);
|
|
52
|
-
expect(forms).toHaveLength(1);
|
|
53
|
-
expect(forms[0].internalId).toBe('FORM_000005');
|
|
54
|
-
|
|
55
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
56
|
-
await assertions.assertNumberOfFormXObjects(0);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Tests for singular select methods
|
|
60
|
-
test('selectForm returns first form or null', async () => {
|
|
61
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('form-xobject-example.pdf');
|
|
62
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
63
|
-
|
|
64
|
-
// Test with results
|
|
65
|
-
const form = await pdf.page(0).selectForm();
|
|
66
|
-
expect(form).not.toBeNull();
|
|
67
|
-
expect(form!.internalId).toBe('FORM_000001');
|
|
68
|
-
|
|
69
|
-
// Test with PDFDancer class
|
|
70
|
-
const formFromPdf = await pdf.selectForm();
|
|
71
|
-
expect(formFromPdf).not.toBeNull();
|
|
72
|
-
expect(formFromPdf!.internalId).toBe('FORM_000001');
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test('selectFormAt returns first form at position or null', async () => {
|
|
76
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('form-xobject-example.pdf');
|
|
77
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
78
|
-
|
|
79
|
-
const form = await pdf.page(0).selectFormAt(321, 601, 1);
|
|
80
|
-
expect(form).not.toBeNull();
|
|
81
|
-
expect(form!.internalId).toBe('FORM_000005');
|
|
82
|
-
|
|
83
|
-
// Test with no match
|
|
84
|
-
const noMatch = await pdf.page(0).selectFormAt(0, 0);
|
|
85
|
-
expect(noMatch).toBeNull();
|
|
86
|
-
});
|
|
87
|
-
});
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import {ObjectType, PDFDancer} from '../../index';
|
|
3
|
-
import {getImagePath, requireEnvAndFixture} from './test-helpers';
|
|
4
|
-
import {PDFAssertions} from './pdf-assertions';
|
|
5
|
-
|
|
6
|
-
describe('Image E2E Tests (Showcase)', () => {
|
|
7
|
-
test('find images', async () => {
|
|
8
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
9
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
10
|
-
|
|
11
|
-
const images = await pdf.selectImages();
|
|
12
|
-
expect(images.length).toBe(12);
|
|
13
|
-
expect(images[0].type).toBe(ObjectType.IMAGE);
|
|
14
|
-
|
|
15
|
-
const pageImages = await pdf.page(0).selectImages();
|
|
16
|
-
expect(pageImages.length).toBe(2);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test('delete all images', async () => {
|
|
20
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
21
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
22
|
-
|
|
23
|
-
const images = await pdf.selectImages();
|
|
24
|
-
expect(images.length).toBe(12);
|
|
25
|
-
for (const image of images) {
|
|
26
|
-
await image.delete();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
expect(await pdf.selectImages()).toHaveLength(0);
|
|
30
|
-
|
|
31
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
32
|
-
for (const page of await pdf.pages()) {
|
|
33
|
-
await assertions.assertNumberOfImages(0, page.position.pageIndex ?? 0);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test('move image', async () => {
|
|
38
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
39
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
40
|
-
|
|
41
|
-
const images = await pdf.selectImages();
|
|
42
|
-
const image = images[10];
|
|
43
|
-
const position = image.position;
|
|
44
|
-
const originalX = position.getX()!;
|
|
45
|
-
const originalY = position.getY()!;
|
|
46
|
-
expect(position.pageIndex).toBe(5);
|
|
47
|
-
|
|
48
|
-
const newX = 500.1;
|
|
49
|
-
const newY = 600.1;
|
|
50
|
-
await image.moveTo(newX, newY);
|
|
51
|
-
|
|
52
|
-
const moved = (await pdf.page(5).selectImagesAt(newX, newY))[0];
|
|
53
|
-
expect(moved.position).toBeDefined();
|
|
54
|
-
expect(Math.abs(moved.position.getX()! - newX)).toBeLessThanOrEqual(0.05);
|
|
55
|
-
expect(Math.abs(moved.position.getY()! - newY)).toBeLessThanOrEqual(0.05);
|
|
56
|
-
|
|
57
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
58
|
-
await assertions.assertImageAt(newX, newY, 5);
|
|
59
|
-
await assertions.assertNoImageAt(originalX, originalY, 5);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test('find image by position', async () => {
|
|
63
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
64
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
65
|
-
|
|
66
|
-
const none = await pdf.page(5).selectImagesAt(0, 0);
|
|
67
|
-
expect(none.length).toBe(0);
|
|
68
|
-
|
|
69
|
-
const found = await pdf.page(5).selectImagesAt(57, 55, 1);
|
|
70
|
-
expect(found.length).toBe(1);
|
|
71
|
-
expect(found[0].internalId).toBe('IMAGE_000011');
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test('add image via document builder', async () => {
|
|
75
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
76
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
77
|
-
|
|
78
|
-
expect(await pdf.selectImages()).toHaveLength(12);
|
|
79
|
-
expect(await pdf.page(6).selectImages()).toHaveLength(1);
|
|
80
|
-
|
|
81
|
-
const fixturePath = getImagePath('logo-80.png');
|
|
82
|
-
expect(fs.existsSync(fixturePath)).toBe(true);
|
|
83
|
-
|
|
84
|
-
await pdf.newImage()
|
|
85
|
-
.fromFile(fixturePath)
|
|
86
|
-
.at(6, 50.1, 98.0)
|
|
87
|
-
.add();
|
|
88
|
-
|
|
89
|
-
expect(await pdf.selectImages()).toHaveLength(13);
|
|
90
|
-
const pageImages = await pdf.page(6).selectImages();
|
|
91
|
-
expect(pageImages.length).toBe(2);
|
|
92
|
-
|
|
93
|
-
const added = pageImages[1];
|
|
94
|
-
expect(added.position.pageIndex).toBe(6);
|
|
95
|
-
expect(added.internalId).toBe('IMAGE_000013');
|
|
96
|
-
expect(Math.abs(added.position.getX()! - 50.1)).toBeLessThanOrEqual(0.05);
|
|
97
|
-
expect(Math.abs(added.position.getY()! - 98.0)).toBeLessThanOrEqual(0.05);
|
|
98
|
-
|
|
99
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
100
|
-
await assertions.assertImageAt(50.1, 98, 6);
|
|
101
|
-
await assertions.assertNumberOfImages(2, 6);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
test('add image via page builder', async () => {
|
|
105
|
-
const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
|
|
106
|
-
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
107
|
-
|
|
108
|
-
expect(await pdf.selectImages()).toHaveLength(12);
|
|
109
|
-
expect(await pdf.page(6).selectImages()).toHaveLength(1);
|
|
110
|
-
|
|
111
|
-
const fixturePath = getImagePath('logo-80.png');
|
|
112
|
-
expect(fs.existsSync(fixturePath)).toBe(true);
|
|
113
|
-
|
|
114
|
-
await pdf.page(6).newImage()
|
|
115
|
-
.fromFile(fixturePath)
|
|
116
|
-
.at(50.1, 98.0)
|
|
117
|
-
.add();
|
|
118
|
-
|
|
119
|
-
expect(await pdf.selectImages()).toHaveLength(13);
|
|
120
|
-
const pageImages = await pdf.page(6).selectImages();
|
|
121
|
-
expect(pageImages.length).toBe(2);
|
|
122
|
-
|
|
123
|
-
const added = pageImages[1];
|
|
124
|
-
expect(added.position.pageIndex).toBe(6);
|
|
125
|
-
expect(added.internalId).toBe('IMAGE_000013');
|
|
126
|
-
expect(Math.abs(added.position.getX()! - 50.1)).toBeLessThanOrEqual(0.05);
|
|
127
|
-
expect(Math.abs(added.position.getY()! - 98.0)).toBeLessThanOrEqual(0.05);
|
|
128
|
-
|
|
129
|
-
const assertions = await PDFAssertions.create(pdf);
|
|
130
|
-
await assertions.assertImageAt(50.1, 98, 6);
|
|
131
|
-
await assertions.assertNumberOfImages(2, 6);
|
|
132
|
-
});
|
|
133
|
-
});
|