@@ -2,6 +2,35 @@ import { describe, it, expect } from "vitest";
22
33const API_URL = process . env . API_URL || "https://html2pdfapi.com" ;
44
5+ function isPNG ( buffer ) {
6+ // PNG magic bytes: 89 50 4E 47 0D 0A 1A 0A
7+ return buffer [ 0 ] === 0x89 && buffer [ 1 ] === 0x50 && buffer [ 2 ] === 0x4E && buffer [ 3 ] === 0x47 ;
8+ }
9+
10+ function isJPEG ( buffer ) {
11+ // JPEG magic bytes: FF D8 FF
12+ return buffer [ 0 ] === 0xFF && buffer [ 1 ] === 0xD8 && buffer [ 2 ] === 0xFF ;
13+ }
14+
15+ function isWebP ( buffer ) {
16+ // WebP: starts with RIFF....WEBP
17+ const riff = String . fromCharCode ( buffer [ 0 ] , buffer [ 1 ] , buffer [ 2 ] , buffer [ 3 ] ) ;
18+ const webp = String . fromCharCode ( buffer [ 8 ] , buffer [ 9 ] , buffer [ 10 ] , buffer [ 11 ] ) ;
19+ return riff === "RIFF" && webp === "WEBP" ;
20+ }
21+
22+ function isPDF ( buffer ) {
23+ // PDF header: %PDF-
24+ const header = String . fromCharCode ( buffer [ 0 ] , buffer [ 1 ] , buffer [ 2 ] , buffer [ 3 ] , buffer [ 4 ] ) ;
25+ return header === "%PDF-" ;
26+ }
27+
28+ function isMP4 ( buffer ) {
29+ // MP4 ftyp box: bytes 4-7 are "ftyp"
30+ const ftyp = String . fromCharCode ( buffer [ 4 ] , buffer [ 5 ] , buffer [ 6 ] , buffer [ 7 ] ) ;
31+ return ftyp === "ftyp" ;
32+ }
33+
534describe ( "API integration tests" , ( ) => {
635 it ( "should render an image from URL" , async ( ) => {
736 const response = await fetch ( `${ API_URL } /render` , {
@@ -14,8 +43,9 @@ describe("API integration tests", () => {
1443 } ) ;
1544 expect ( response . status ) . toBe ( 200 ) ;
1645 expect ( response . headers . get ( "content-type" ) ) . toContain ( "image/" ) ;
17- const buffer = await response . arrayBuffer ( ) ;
46+ const buffer = new Uint8Array ( await response . arrayBuffer ( ) ) ;
1847 expect ( buffer . byteLength ) . toBeGreaterThan ( 0 ) ;
48+ expect ( isPNG ( buffer ) ) . toBe ( true ) ;
1949 } ) ;
2050
2151 it ( "should render a PDF from URL" , async ( ) => {
@@ -29,8 +59,9 @@ describe("API integration tests", () => {
2959 } ) ;
3060 expect ( response . status ) . toBe ( 200 ) ;
3161 expect ( response . headers . get ( "content-type" ) ) . toContain ( "application/pdf" ) ;
32- const buffer = await response . arrayBuffer ( ) ;
62+ const buffer = new Uint8Array ( await response . arrayBuffer ( ) ) ;
3363 expect ( buffer . byteLength ) . toBeGreaterThan ( 0 ) ;
64+ expect ( isPDF ( buffer ) ) . toBe ( true ) ;
3465 } ) ;
3566
3667 it ( "should render HTML content directly" , async ( ) => {
@@ -44,6 +75,9 @@ describe("API integration tests", () => {
4475 } ) ;
4576 expect ( response . status ) . toBe ( 200 ) ;
4677 expect ( response . headers . get ( "content-type" ) ) . toContain ( "image/" ) ;
78+ const buffer = new Uint8Array ( await response . arrayBuffer ( ) ) ;
79+ expect ( buffer . byteLength ) . toBeGreaterThan ( 0 ) ;
80+ expect ( isPNG ( buffer ) ) . toBe ( true ) ;
4781 } ) ;
4882
4983 it ( "should return 400 for missing url and html" , async ( ) => {
@@ -94,6 +128,9 @@ describe("API integration tests", () => {
94128 } ) ,
95129 } ) ;
96130 expect ( response . status ) . toBe ( 200 ) ;
131+ const buffer = new Uint8Array ( await response . arrayBuffer ( ) ) ;
132+ expect ( buffer . byteLength ) . toBeGreaterThan ( 0 ) ;
133+ expect ( isPNG ( buffer ) ) . toBe ( true ) ;
97134 } ) ;
98135
99136 it ( "should support webp output format" , async ( ) => {
@@ -108,6 +145,24 @@ describe("API integration tests", () => {
108145 } ) ;
109146 expect ( response . status ) . toBe ( 200 ) ;
110147 expect ( response . headers . get ( "content-type" ) ) . toContain ( "image/webp" ) ;
148+ const buffer = new Uint8Array ( await response . arrayBuffer ( ) ) ;
149+ expect ( buffer . byteLength ) . toBeGreaterThan ( 0 ) ;
150+ expect ( isWebP ( buffer ) ) . toBe ( true ) ;
151+ } ) ;
152+
153+ it ( "should capture HTML with embedded resources" , async ( ) => {
154+ const response = await fetch ( `${ API_URL } /render` , {
155+ method : "POST" ,
156+ headers : { "Content-Type" : "application/json" } ,
157+ body : JSON . stringify ( {
158+ url : "https://example.com" ,
159+ type : "html" ,
160+ } ) ,
161+ } ) ;
162+ expect ( response . status ) . toBe ( 200 ) ;
163+ const text = await response . text ( ) ;
164+ expect ( text ) . toContain ( "<!DOCTYPE html>" ) ;
165+ expect ( text ) . toContain ( "<html" ) ;
111166 } ) ;
112167
113168 it ( "should not expose internal error details" , async ( ) => {
@@ -176,3 +231,23 @@ describe("API performance tests", () => {
176231 expect ( disposition ) . toContain ( "filename=" ) ;
177232 } ) ;
178233} ) ;
234+
235+ describe ( "API video tests" , ( ) => {
236+ it ( "should render a video from URL" , async ( ) => {
237+ const response = await fetch ( `${ API_URL } /render` , {
238+ method : "POST" ,
239+ headers : { "Content-Type" : "application/json" } ,
240+ body : JSON . stringify ( {
241+ url : "https://example.com" ,
242+ type : "video" ,
243+ video : { fps : 24 } ,
244+ render : { scroll : { animate : true , duration : 1000 } } ,
245+ } ) ,
246+ } ) ;
247+ expect ( response . status ) . toBe ( 200 ) ;
248+ expect ( response . headers . get ( "content-type" ) ) . toContain ( "video/" ) ;
249+ const buffer = new Uint8Array ( await response . arrayBuffer ( ) ) ;
250+ expect ( buffer . byteLength ) . toBeGreaterThan ( 1000 ) ;
251+ expect ( isMP4 ( buffer ) ) . toBe ( true ) ;
252+ } , 60000 ) ;
253+ } ) ;
0 commit comments