pdfdancer-client-typescript 1.0.13 → 1.0.15

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 (45) hide show
  1. package/.eslintrc.js +26 -18
  2. package/.github/workflows/ci.yml +51 -2
  3. package/.github/workflows/daily-tests.yml +54 -0
  4. package/README.md +50 -6
  5. package/dist/__tests__/e2e/test-helpers.d.ts.map +1 -1
  6. package/dist/__tests__/e2e/test-helpers.js +17 -5
  7. package/dist/__tests__/e2e/test-helpers.js.map +1 -1
  8. package/dist/fingerprint.d.ts.map +1 -1
  9. package/dist/fingerprint.js +16 -5
  10. package/dist/fingerprint.js.map +1 -1
  11. package/dist/index.d.ts +2 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +4 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/models.d.ts +18 -15
  16. package/dist/models.d.ts.map +1 -1
  17. package/dist/models.js +21 -18
  18. package/dist/models.js.map +1 -1
  19. package/dist/pdfdancer_v1.d.ts +71 -3
  20. package/dist/pdfdancer_v1.d.ts.map +1 -1
  21. package/dist/pdfdancer_v1.js +301 -35
  22. package/dist/pdfdancer_v1.js.map +1 -1
  23. package/docs/openapi.yml +637 -73
  24. package/jest.config.js +1 -1
  25. package/package.json +2 -2
  26. package/src/__tests__/e2e/acroform.test.ts +58 -0
  27. package/src/__tests__/e2e/form_x_object.test.ts +29 -0
  28. package/src/__tests__/e2e/image-showcase.test.ts +6 -6
  29. package/src/__tests__/e2e/image.test.ts +39 -5
  30. package/src/__tests__/e2e/line-showcase.test.ts +6 -11
  31. package/src/__tests__/e2e/line.test.ts +63 -7
  32. package/src/__tests__/e2e/page-showcase.test.ts +12 -12
  33. package/src/__tests__/e2e/page.test.ts +3 -3
  34. package/src/__tests__/e2e/paragraph-showcase.test.ts +0 -8
  35. package/src/__tests__/e2e/paragraph.test.ts +64 -8
  36. package/src/__tests__/e2e/path.test.ts +33 -4
  37. package/src/__tests__/e2e/snapshot-showcase.test.ts +10 -10
  38. package/src/__tests__/e2e/snapshot.test.ts +18 -18
  39. package/src/__tests__/e2e/test-helpers.ts +16 -5
  40. package/src/__tests__/e2e/token_from_env.test.ts +0 -15
  41. package/src/__tests__/retry-mechanism.test.ts +420 -0
  42. package/src/fingerprint.ts +20 -7
  43. package/src/index.ts +3 -1
  44. package/src/models.ts +21 -17
  45. package/src/pdfdancer_v1.ts +467 -71
@@ -32,7 +32,6 @@ describe('Paragraph E2E Tests (v2 API)', () => {
32
32
  expectWithin(last.position.boundingRect?.y, 496, 2);
33
33
 
34
34
  expect(last.objectRef().status).toBeDefined();
35
- expect(last.objectRef().status?.isEncodable()).toBe(true);
36
35
  expect(last.objectRef().status?.getFontType()).toBe(FontType.EMBEDDED);
37
36
  expect(last.objectRef().status?.isModified()).toBe(false);
38
37
  });
@@ -112,7 +111,6 @@ describe('Paragraph E2E Tests (v2 API)', () => {
112
111
  expect(movedParas.length).toBeGreaterThan(0);
113
112
  const moved = movedParas[0];
114
113
  expect(moved.objectRef().status).toBeDefined();
115
- expect(moved.objectRef().status?.isEncodable()).toBe(true);
116
114
  expect(moved.objectRef().status?.getFontType()).toBe(FontType.STANDARD);
117
115
  expect(moved.objectRef().status?.isModified()).toBe(true);
118
116
 
@@ -134,7 +132,7 @@ describe('Paragraph E2E Tests (v2 API)', () => {
134
132
  // This should issue a warning about an embedded font modification
135
133
  expect(typeof result).toBe('object');
136
134
  expect((result as any).warning).toBeDefined();
137
- expect((result as any).warning).toContain('You are using an embedded font and modified the text.');
135
+ expect((result as any).warning).toBe("Text is not encodable with your current font, we are using 'Poppins-Bold' as a fallback font instead.");
138
136
 
139
137
  await assertNewParagraphExists(pdf);
140
138
 
@@ -142,13 +140,12 @@ describe('Paragraph E2E Tests (v2 API)', () => {
142
140
  expect(modifiedParas.length).toBeGreaterThan(0);
143
141
  const modified = modifiedParas[0];
144
142
  expect(modified.objectRef().status).toBeDefined();
145
- expect(modified.objectRef().status?.isEncodable()).toBe(true);
146
143
  expect(modified.objectRef().status?.getFontType()).toBe(FontType.EMBEDDED);
147
144
  expect(modified.objectRef().status?.isModified()).toBe(true);
148
145
 
149
146
  const assertions = await PDFAssertions.create(pdf);
150
- await assertions.assertTextlineHasFont('Awesomely', 'IXKSWR+Poppins-Bold', 45, 0);
151
- await assertions.assertTextlineHasFont('Obvious!', 'IXKSWR+Poppins-Bold', 45, 0);
147
+ await assertions.assertTextlineHasFontMatching('Awesomely', 'Poppins-Bold', 45, 0);
148
+ await assertions.assertTextlineHasFontMatching('Obvious!', 'Poppins-Bold', 45, 0);
152
149
  await assertions.assertTextlineHasColor('Awesomely', new Color(255, 255, 255), 0);
153
150
  await assertions.assertTextlineHasColor('Obvious!', new Color(255, 255, 255), 0);
154
151
  });
@@ -543,8 +540,8 @@ describe('Paragraph E2E Tests (v2 API)', () => {
543
540
  await para.edit().replace('Awesomely\nObvious!').apply();
544
541
 
545
542
  const assertions = await PDFAssertions.create(pdf);
546
- await assertions.assertTextlineHasFont('Awesomely', 'IXKSWR+Poppins-Bold', 45, 0);
547
- await assertions.assertTextlineHasFont('Obvious!', 'IXKSWR+Poppins-Bold', 45, 0);
543
+ await assertions.assertTextlineHasFontMatching('Awesomely', 'Poppins-Bold', 45, 0);
544
+ await assertions.assertTextlineHasFontMatching('Obvious!', 'Poppins-Bold', 45, 0);
548
545
  await assertions.assertTextlineHasColor('Awesomely', new Color(255, 255, 255), 0);
549
546
  await assertions.assertTextlineHasColor('Obvious!', new Color(255, 255, 255), 0);
550
547
  });
@@ -624,4 +621,63 @@ describe('Paragraph E2E Tests (v2 API)', () => {
624
621
  expect(StandardFonts.ZAPF_DINGBATS).toBe('ZapfDingbats');
625
622
  });
626
623
 
624
+ // Tests for singular select methods
625
+ test('selectParagraph returns first paragraph or null', async () => {
626
+ const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
627
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
628
+
629
+ // Test with results
630
+ const para = await pdf.page(0).selectParagraph();
631
+ expect(para).not.toBeNull();
632
+ expect(para!.internalId).toBe('PARAGRAPH_000003');
633
+
634
+ // Test with PDFDancer class
635
+ const paraFromPdf = await pdf.selectParagraph();
636
+ expect(paraFromPdf).not.toBeNull();
637
+ expect(paraFromPdf!.internalId).toBe('PARAGRAPH_000003');
638
+ });
639
+
640
+ test('selectParagraphStartingWith returns first match or null', async () => {
641
+ const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
642
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
643
+
644
+ const para = await pdf.page(0).selectParagraphStartingWith('The Complete');
645
+ expect(para).not.toBeNull();
646
+ expect(para!.internalId).toBe('PARAGRAPH_000004');
647
+
648
+ // Test with no match
649
+ const noMatch = await pdf.page(0).selectParagraphStartingWith('NoMatch');
650
+ expect(noMatch).toBeNull();
651
+ });
652
+
653
+ test('selectParagraphMatching returns first match or null', async () => {
654
+ const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
655
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
656
+
657
+ const para = await pdf.page(0).selectParagraphMatching('.*Complete.*');
658
+ expect(para).not.toBeNull();
659
+ expect(para!.internalId).toBe('PARAGRAPH_000004');
660
+
661
+ // Test with PDFDancer class
662
+ const paraFromPdf = await pdf.selectParagraphMatching('.*Complete.*');
663
+ expect(paraFromPdf).not.toBeNull();
664
+
665
+ // Test with no match
666
+ const noMatch = await pdf.page(0).selectParagraphMatching('.*NOT FOUND.*');
667
+ expect(noMatch).toBeNull();
668
+ });
669
+
670
+ test('selectParagraphAt returns first paragraph at position or null', async () => {
671
+ const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
672
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
673
+
674
+ const para = await pdf.page(0).selectParagraphAt(54, 496, 10);
675
+ expect(para).not.toBeNull();
676
+ expect(para!.internalId).toBe('PARAGRAPH_000004');
677
+
678
+ // Test with no match
679
+ const noMatch = await pdf.page(0).selectParagraphAt(1000, 1000, 1);
680
+ expect(noMatch).toBeNull();
681
+ });
682
+
627
683
  });
@@ -10,7 +10,7 @@ describe('Path E2E Tests (New API)', () => {
10
10
 
11
11
  test('select paths', async () => {
12
12
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
13
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
13
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
14
14
 
15
15
  const paths = await pdf.selectPaths();
16
16
  expect(paths).toHaveLength(9);
@@ -25,7 +25,7 @@ describe('Path E2E Tests (New API)', () => {
25
25
 
26
26
  test('select paths by position', async () => {
27
27
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
28
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
28
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
29
29
 
30
30
  const paths = await pdf.page(0).selectPathsAt(80, 720);
31
31
  expect(paths).toHaveLength(1);
@@ -34,7 +34,7 @@ describe('Path E2E Tests (New API)', () => {
34
34
 
35
35
  test('delete path', async () => {
36
36
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
37
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
37
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
38
38
 
39
39
  let paths = await pdf.page(0).selectPathsAt(80, 720);
40
40
  expect(paths).toHaveLength(1);
@@ -56,7 +56,7 @@ describe('Path E2E Tests (New API)', () => {
56
56
 
57
57
  test('move path', async () => {
58
58
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
59
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
59
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
60
60
 
61
61
  const [path] = await pdf.page(0).selectPathsAt(80, 720);
62
62
  const pos = path.position;
@@ -76,4 +76,33 @@ describe('Path E2E Tests (New API)', () => {
76
76
  const assertions = await PDFAssertions.create(pdf);
77
77
  await assertions.assertPathIsAt('PATH_000001', 50.1, 100);
78
78
  });
79
+
80
+ // Tests for singular select methods
81
+ test('selectPath returns first path or null', async () => {
82
+ const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
83
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
84
+
85
+ // Test with PDFDancer class (document-level)
86
+ const pathFromPdf = await pdf.selectPath();
87
+ expect(pathFromPdf).not.toBeNull();
88
+ expect(pathFromPdf!.internalId).toBe('PATH_000001');
89
+
90
+ // Test with page-level using position since paths may require coordinates
91
+ const pathOnPage = await pdf.page(0).selectPathAt(80, 720);
92
+ expect(pathOnPage).not.toBeNull();
93
+ expect(pathOnPage!.internalId).toBe('PATH_000001');
94
+ });
95
+
96
+ test('selectPathAt returns first path at position or null', async () => {
97
+ const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
98
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
99
+
100
+ const path = await pdf.page(0).selectPathAt(80, 720);
101
+ expect(path).not.toBeNull();
102
+ expect(path!.internalId).toBe('PATH_000001');
103
+
104
+ // Test with no match
105
+ const noMatch = await pdf.page(0).selectPathAt(1000, 1000);
106
+ expect(noMatch).toBeNull();
107
+ });
79
108
  });
@@ -4,7 +4,7 @@ import {requireEnvAndFixture} from './test-helpers';
4
4
  describe('Snapshot E2E Tests (Showcase)', () => {
5
5
  test('page snapshot matches select paragraphs', async () => {
6
6
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
7
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
7
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
8
8
 
9
9
  const snapshot = await pdf.getPageSnapshot(0);
10
10
  const snapshotParagraphs = snapshot.elements.filter(e => e.type === ObjectType.PARAGRAPH);
@@ -18,7 +18,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
18
18
 
19
19
  test('page snapshot matches select images', async () => {
20
20
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
21
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
21
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
22
22
 
23
23
  const snapshot = await pdf.getPageSnapshot(0);
24
24
  const snapshotImages = snapshot.elements.filter(e => e.type === ObjectType.IMAGE);
@@ -34,7 +34,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
34
34
 
35
35
  test('page snapshot matches select forms', async () => {
36
36
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
37
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
37
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
38
38
 
39
39
  const snapshot = await pdf.getPageSnapshot(0);
40
40
  const snapshotForms = snapshot.elements.filter(e => e.type === ObjectType.FORM_X_OBJECT);
@@ -50,7 +50,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
50
50
 
51
51
  test('page snapshot matches select form fields', async () => {
52
52
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
53
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
53
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
54
54
 
55
55
  const snapshot = await pdf.getPageSnapshot(0);
56
56
  const snapshotFields = snapshot.elements.filter(e => [
@@ -71,7 +71,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
71
71
 
72
72
  test('page snapshot contains all element types', async () => {
73
73
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
74
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
74
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
75
75
 
76
76
  const snapshot = await pdf.getPageSnapshot(0);
77
77
  const paragraphCount = snapshot.elements.filter(e => e.type === ObjectType.PARAGRAPH).length;
@@ -87,7 +87,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
87
87
 
88
88
  test('document snapshot matches all pages', async () => {
89
89
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
90
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
90
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
91
91
 
92
92
  const docSnapshot = await pdf.getDocumentSnapshot();
93
93
  for (let i = 0; i < docSnapshot.pageCount; i++) {
@@ -103,7 +103,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
103
103
 
104
104
  test('type filter matches select method', async () => {
105
105
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
106
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
106
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
107
107
 
108
108
  const snapshot = await pdf.getPageSnapshot(0, [ObjectType.PARAGRAPH]);
109
109
  const selected = await pdf.page(0).selectParagraphs();
@@ -118,7 +118,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
118
118
 
119
119
  test('multiple type filters combined', async () => {
120
120
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
121
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
121
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
122
122
 
123
123
  const snapshot = await pdf.getPageSnapshot(0, [ObjectType.PARAGRAPH, ObjectType.TEXT_LINE]);
124
124
  expect(snapshot.elements.every(e => e.type === ObjectType.PARAGRAPH || e.type === ObjectType.TEXT_LINE)).toBe(true);
@@ -130,7 +130,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
130
130
 
131
131
  test('total element count matches expected', async () => {
132
132
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
133
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
133
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
134
134
 
135
135
  const elements = await pdf.selectElements();
136
136
  expect(elements.length).toBe(99);
@@ -143,7 +143,7 @@ describe('Snapshot E2E Tests (Showcase)', () => {
143
143
 
144
144
  test('snapshot consistency across multiple pages', async () => {
145
145
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Showcase.pdf');
146
- const pdf = await PDFDancer.open(pdfData, token, baseUrl, 30000);
146
+ const pdf = await PDFDancer.open(pdfData, token, baseUrl);
147
147
 
148
148
  const docSnapshot = await pdf.getDocumentSnapshot();
149
149
  expect(docSnapshot.pageCount).toBeGreaterThan(1);
@@ -9,7 +9,7 @@ describe('Snapshot E2E Tests', () => {
9
9
 
10
10
  test('get document snapshot', async () => {
11
11
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
12
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
12
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
13
13
 
14
14
  const snapshot = await client.getDocumentSnapshot();
15
15
 
@@ -42,7 +42,7 @@ describe('Snapshot E2E Tests', () => {
42
42
 
43
43
  test('get document snapshot with type filter', async () => {
44
44
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
45
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
45
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
46
46
 
47
47
  // Get snapshot filtered by paragraphs only
48
48
  const snapshot = await client.getDocumentSnapshot([ObjectType.PARAGRAPH]);
@@ -59,7 +59,7 @@ describe('Snapshot E2E Tests', () => {
59
59
 
60
60
  test('get document snapshot with multiple type filters', async () => {
61
61
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
62
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
62
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
63
63
 
64
64
  // Get snapshot filtered by paragraphs and images
65
65
  const snapshot = await client.getDocumentSnapshot([ObjectType.PARAGRAPH, ObjectType.IMAGE]);
@@ -75,7 +75,7 @@ describe('Snapshot E2E Tests', () => {
75
75
 
76
76
  test('get page snapshot', async () => {
77
77
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
78
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
78
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
79
79
 
80
80
  const pageSnapshot = await client.getPageSnapshot(0);
81
81
 
@@ -103,7 +103,7 @@ describe('Snapshot E2E Tests', () => {
103
103
 
104
104
  test('get page snapshot with type filter', async () => {
105
105
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
106
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
106
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
107
107
 
108
108
  // Get page snapshot filtered by images only
109
109
  const pageSnapshot = await client.getPageSnapshot(0, [ObjectType.IMAGE]);
@@ -118,7 +118,7 @@ describe('Snapshot E2E Tests', () => {
118
118
 
119
119
  test('get page snapshot via PageClient', async () => {
120
120
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
121
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
121
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
122
122
 
123
123
  const page = client.page(1);
124
124
  const pageSnapshot = await page.getSnapshot();
@@ -132,7 +132,7 @@ describe('Snapshot E2E Tests', () => {
132
132
 
133
133
  test('get page snapshot via PageClient with type filter', async () => {
134
134
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
135
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
135
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
136
136
 
137
137
  const page = client.page(0);
138
138
  const pageSnapshot = await page.getSnapshot([ObjectType.PARAGRAPH]);
@@ -147,7 +147,7 @@ describe('Snapshot E2E Tests', () => {
147
147
 
148
148
  test('DocumentSnapshot helper methods', async () => {
149
149
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
150
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
150
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
151
151
 
152
152
  const snapshot = await client.getDocumentSnapshot();
153
153
 
@@ -179,7 +179,7 @@ describe('Snapshot E2E Tests', () => {
179
179
 
180
180
  test('PageSnapshot helper methods', async () => {
181
181
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
182
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
182
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
183
183
 
184
184
  const pageSnapshot = await client.getPageSnapshot(0);
185
185
 
@@ -200,7 +200,7 @@ describe('Snapshot E2E Tests', () => {
200
200
 
201
201
  test('snapshot with form fields', async () => {
202
202
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('mixed-form-types.pdf');
203
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
203
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
204
204
 
205
205
  // Form fields can be TEXT_FIELD, CHECKBOX, or RADIO_BUTTON
206
206
  const snapshot = await client.getDocumentSnapshot([
@@ -224,7 +224,7 @@ describe('Snapshot E2E Tests', () => {
224
224
 
225
225
  test('snapshot with paths', async () => {
226
226
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
227
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
227
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
228
228
 
229
229
  const snapshot = await client.getDocumentSnapshot([ObjectType.PATH]);
230
230
 
@@ -242,7 +242,7 @@ describe('Snapshot E2E Tests', () => {
242
242
 
243
243
  test('compare snapshot with individual find operations', async () => {
244
244
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
245
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
245
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
246
246
 
247
247
  // Get snapshot
248
248
  const snapshot = await client.getPageSnapshot(0);
@@ -258,7 +258,7 @@ describe('Snapshot E2E Tests', () => {
258
258
 
259
259
  test('snapshot fonts information', async () => {
260
260
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
261
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
261
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
262
262
 
263
263
  const snapshot = await client.getDocumentSnapshot();
264
264
 
@@ -269,16 +269,17 @@ describe('Snapshot E2E Tests', () => {
269
269
  // If there are fonts, verify their structure
270
270
  if (snapshot.fonts.length > 0) {
271
271
  for (const font of snapshot.fonts) {
272
- expect(font.fontName).toBeDefined();
273
- expect(font.fontType).toBeDefined();
274
- expect(typeof font.similarityScore).toBe('number');
272
+ expect(font.documentFontName).toBeDefined();
273
+ expect(font.systemFontName).toBeDefined();
274
+ expect(typeof font.documentFontName).toBe('string');
275
+ expect(typeof font.systemFontName).toBe('string');
275
276
  }
276
277
  }
277
278
  });
278
279
 
279
280
  test('snapshot on empty page', async () => {
280
281
  const [baseUrl, token, pdfData] = await requireEnvAndFixture('Empty.pdf');
281
- const client = await PDFDancer.open(pdfData, token, baseUrl, 30000);
282
+ const client = await PDFDancer.open(pdfData, token, baseUrl);
282
283
 
283
284
  const snapshot = await client.getDocumentSnapshot();
284
285
 
@@ -293,4 +294,3 @@ describe('Snapshot E2E Tests', () => {
293
294
  expect(Array.isArray(page0Snapshot!.elements)).toBe(true);
294
295
  });
295
296
  });
296
-
@@ -4,12 +4,13 @@
4
4
 
5
5
  import * as fs from 'fs';
6
6
  import * as path from 'path';
7
+ import os from "os";
7
8
 
8
9
  /**
9
10
  * Get the base URL from environment variable or default
10
11
  */
11
12
  export function getBaseUrl(): string {
12
- return process.env.PDFDANCER_BASE_URL || 'http://localhost:8080';
13
+ return (process.env.PDFDANCER_BASE_URL || 'http://localhost:8080').trim();
13
14
  }
14
15
 
15
16
  /**
@@ -42,11 +43,16 @@ export function readToken(): string | null {
42
43
  export async function serverUp(baseUrl: string): Promise<boolean> {
43
44
  try {
44
45
  const response = await fetch(`${baseUrl}/ping`, {
45
- signal: AbortSignal.timeout(3000)
46
+ signal: AbortSignal.timeout(60000)
46
47
  });
47
48
  const text = await response.text();
48
- return response.status === 200 && text.includes('Pong');
49
- } catch {
49
+ let pongReceived = response.status === 200 && text.includes('Pong');
50
+ if (!pongReceived) {
51
+ console.error(`Server did not respond with Pong. Response: ${text}, status ${response.status}`);
52
+ }
53
+ return pongReceived;
54
+ } catch (e) {
55
+ console.error("Server down", e)
50
56
  return false;
51
57
  }
52
58
  }
@@ -97,7 +103,12 @@ export async function requireEnvAndFixture(pdfFilename: string): Promise<[string
97
103
  * Helper to open temporary file path (for Node.js environment)
98
104
  */
99
105
  export function createTempPath(filename: string): string {
100
- const tmpDir = process.env.TMPDIR || '/tmp';
106
+ const tmpDir =
107
+ process.env.TMPDIR ||
108
+ process.env.TEMP ||
109
+ process.env.TMP ||
110
+ os.tmpdir(); // reliable built-in fallback
111
+
101
112
  return path.join(tmpDir, filename);
102
113
  }
103
114
 
@@ -3,7 +3,6 @@ import {PDFDancer} from "../../pdfdancer_v1";
3
3
  import {HttpClientException, ValidationException} from "../../exceptions";
4
4
 
5
5
  describe('Env Token E2E Tests', () => {
6
- const MISSING_TOKEN_MESSAGE = "Missing PDFDancer API token. Pass a token via the `token` argument or set the PDFDANCER_TOKEN environment variable.";
7
6
  let originalToken: string | undefined;
8
7
  let originalBaseUrl: string | undefined;
9
8
  let baseUrl: string;
@@ -43,20 +42,6 @@ describe('Env Token E2E Tests', () => {
43
42
  restoreEnv();
44
43
  });
45
44
 
46
- test('requires token from env or argument', async () => {
47
- delete process.env.PDFDANCER_TOKEN;
48
-
49
- await expect(async () => {
50
- try {
51
- await PDFDancer.open(pdfData, undefined, baseUrl);
52
- } catch (error) {
53
- expect(error).toBeInstanceOf(ValidationException);
54
- expect((error as Error).message).toBe(MISSING_TOKEN_MESSAGE);
55
- throw error;
56
- }
57
- }).rejects.toThrow(MISSING_TOKEN_MESSAGE);
58
- });
59
-
60
45
  test('opens with token from env', async () => {
61
46
  process.env.PDFDANCER_TOKEN = validToken;
62
47
  const client = await PDFDancer.open(pdfData, undefined, baseUrl);