Skip to content

Commit 58b4cf0

Browse files
authored
PDF support (#61)
PDF suport feature complete
1 parent 28f7e8c commit 58b4cf0

File tree

9 files changed

+394
-27
lines changed

9 files changed

+394
-27
lines changed
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading.Tasks;
4+
using PuppeteerSharp.Tests.Puppeteer;
5+
using Xunit;
6+
using PdfSharp.Pdf.IO;
7+
8+
namespace PuppeteerSharp.Tests.Page
9+
{
10+
public class PdfTests : IDisposable
11+
{
12+
private string _baseDirectory;
13+
Browser _browser;
14+
15+
public PdfTests()
16+
{
17+
_baseDirectory = Path.Combine(Directory.GetCurrentDirectory(), "test-pdf");
18+
var dirInfo = new DirectoryInfo(_baseDirectory);
19+
20+
if (dirInfo.Exists)
21+
{
22+
dirInfo.Delete(true);
23+
}
24+
25+
dirInfo.Create();
26+
_browser = PuppeteerSharp.Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions,
27+
TestConstants.ChromiumRevision).GetAwaiter().GetResult();
28+
}
29+
30+
public void Dispose()
31+
{
32+
_browser.CloseAsync().GetAwaiter().GetResult();
33+
}
34+
35+
[Fact]
36+
public async Task ShouldBeAbleToSaveFile()
37+
{
38+
var outputFile = Path.Combine(_baseDirectory, "output.pdf");
39+
var fileInfo = new FileInfo(outputFile);
40+
41+
if (fileInfo.Exists)
42+
{
43+
fileInfo.Delete();
44+
}
45+
46+
var page = await _browser.NewPageAsync();
47+
await page.PdfAsync(new PdfOptions
48+
{
49+
Path = outputFile
50+
});
51+
52+
fileInfo = new FileInfo(outputFile);
53+
Assert.True(new FileInfo(outputFile).Length > 0);
54+
55+
if (fileInfo.Exists)
56+
{
57+
fileInfo.Delete();
58+
}
59+
}
60+
61+
[Fact]
62+
public async Task ShouldDefaultToPrintInLetterFormat()
63+
{
64+
var page = await _browser.NewPageAsync();
65+
66+
var document = PdfReader.Open(await page.PdfAsync(), PdfDocumentOpenMode.ReadOnly);
67+
68+
Assert.Equal(1, document.Pages.Count);
69+
Assert.Equal(8.5, TruncateDouble(document.Pages[0].Width.Inch, 1));
70+
Assert.Equal(11, TruncateDouble(document.Pages[0].Height.Inch, 0));
71+
}
72+
73+
[Fact]
74+
public async Task ShouldSupportSettingCustomFormat()
75+
{
76+
var page = await _browser.NewPageAsync();
77+
78+
var document = PdfReader.Open(await page.PdfAsync(new PdfOptions
79+
{
80+
Format = "a4"
81+
}), PdfDocumentOpenMode.ReadOnly);
82+
83+
Assert.Equal(1, document.Pages.Count);
84+
Assert.Equal(8.2, TruncateDouble(document.Pages[0].Width.Inch, 1));
85+
Assert.Equal(842, document.Pages[0].Height.Point);
86+
}
87+
88+
[Fact]
89+
public async Task ShouldSupportSettingPaperWidthAndHeight()
90+
{
91+
var page = await _browser.NewPageAsync();
92+
93+
var document = PdfReader.Open(await page.PdfAsync(new PdfOptions
94+
{
95+
Width = "10in",
96+
Height = "10in"
97+
}), PdfDocumentOpenMode.ReadOnly);
98+
99+
Assert.Equal(1, document.Pages.Count);
100+
Assert.Equal(10, TruncateDouble(document.Pages[0].Width.Inch, 0));
101+
Assert.Equal(10, TruncateDouble(document.Pages[0].Height.Inch, 0));
102+
}
103+
104+
[Fact]
105+
public async Task ShouldPrintMultiplePages()
106+
{
107+
var page = await _browser.NewPageAsync();
108+
await page.GoToAsync(TestConstants.ServerUrl + "/grid.html");
109+
// Define width and height in CSS pixels.
110+
var width = 50 * 5 + 1;
111+
var height = 50 * 5 + 1;
112+
var document = PdfReader.Open(await page.PdfAsync(new PdfOptions
113+
{
114+
Width = width,
115+
Height = height
116+
}));
117+
118+
Assert.Equal(8, document.Pages.Count);
119+
Assert.Equal(CssPixelsToInches(width), TruncateDouble(document.Pages[0].Width.Inch, 0));
120+
Assert.Equal(CssPixelsToInches(height), TruncateDouble(document.Pages[0].Height.Inch, 0));
121+
}
122+
123+
[Fact]
124+
public async Task ShouldSupportPageRanges()
125+
{
126+
var page = await _browser.NewPageAsync();
127+
await page.GoToAsync(TestConstants.ServerUrl + "/grid.html");
128+
// Define width and height in CSS pixels.
129+
var width = 50 * 5 + 1;
130+
var height = 50 * 5 + 1;
131+
var document = PdfReader.Open(await page.PdfAsync(new PdfOptions
132+
{
133+
Width = width,
134+
Height = height,
135+
PageRanges = "1,4-7"
136+
}));
137+
138+
Assert.Equal(5, document.Pages.Count);
139+
}
140+
141+
[Fact]
142+
public async Task ShowThrowFormatIsUnknown()
143+
{
144+
var page = await _browser.NewPageAsync();
145+
var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>
146+
{
147+
await page.PdfAsync(new PdfOptions
148+
{
149+
Format = "something"
150+
});
151+
});
152+
153+
Assert.Equal("Unknown paper format", exception.Message);
154+
}
155+
156+
[Fact]
157+
public async Task ShouldThrowIfUnitsAreUnknown()
158+
{
159+
var page = await _browser.NewPageAsync();
160+
var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>
161+
{
162+
await page.PdfAsync(new PdfOptions
163+
{
164+
Width = "10em"
165+
});
166+
});
167+
168+
Assert.Contains("Failed to parse parameter value", exception.Message);
169+
}
170+
171+
private double TruncateDouble(double value, int precision)
172+
{
173+
double step = Math.Pow(10, precision);
174+
double tmp = Math.Truncate(step * value);
175+
return tmp / step;
176+
}
177+
178+
private double CssPixelsToInches(int pixels)
179+
{
180+
return pixels / 96;
181+
}
182+
}
183+
}

lib/PuppeteerSharp.Tests/Puppeteer/DownloaderTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ public async Task ShouldDownloadChromium()
1919
dirInfo.Delete(true);
2020
}
2121

22-
await downloader.DownloadRevisionAsync(PuppeteerLaunchTests.ChromiumRevision);
23-
Assert.True(new FileInfo(downloader.GetExecutablePath(PuppeteerLaunchTests.ChromiumRevision)).Exists);
22+
await downloader.DownloadRevisionAsync(TestConstants.ChromiumRevision);
23+
Assert.True(new FileInfo(downloader.GetExecutablePath(TestConstants.ChromiumRevision)).Exists);
2424
}
2525
}
2626
}

lib/PuppeteerSharp.Tests/Puppeteer/PuppeteerLaunchTests.cs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,21 @@ namespace PuppeteerSharp.Tests.Puppeteer
1010
{
1111
public class PuppeteerLaunchTests
1212
{
13-
private const int HttpsPort = 8908;
14-
private const string HttpsPrefix = "https://localhost:8908";
15-
public const int ChromiumRevision = 526987;
16-
17-
private Dictionary<string, object> _defaultBrowserOptions = new Dictionary<string, object>()
18-
{
19-
{ "slowMo", Convert.ToInt32(Environment.GetEnvironmentVariable("SLOW_MO") ?? "0") },
20-
{ "headless", Convert.ToBoolean(Environment.GetEnvironmentVariable("HEADLESS") ?? "true") },
21-
{ "args", new[] { "--no-sandbox" }},
22-
{ "timeout", 0}
23-
};
24-
2513
public PuppeteerLaunchTests()
2614
{
27-
Downloader.CreateDefault().DownloadRevisionAsync(ChromiumRevision).GetAwaiter().GetResult();
15+
Downloader.CreateDefault().DownloadRevisionAsync(TestConstants.ChromiumRevision).GetAwaiter().GetResult();
2816
}
2917

3018
[Fact]
3119
public async Task ShouldSupportIgnoreHTTPSErrorsOption()
3220
{
33-
var options = _defaultBrowserOptions.Clone();
21+
var options = TestConstants.DefaultBrowserOptions.Clone();
3422
options.Add("ignoreHTTPSErrors", true);
3523

36-
var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(options, ChromiumRevision);
24+
var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(options, TestConstants.ChromiumRevision);
3725
var page = await browser.NewPageAsync();
3826

39-
var response = await page.GoToAsync(HttpsPrefix + "/empty.html");
27+
var response = await page.GoToAsync(TestConstants.HttpsPrefix + "/empty.html");
4028
Assert.Equal(response.Status.ToString(), "OK");
4129

4230
await browser.CloseAsync();

lib/PuppeteerSharp.Tests/PuppeteerSharp.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
1111
<PackageReference Include="xunit" Version="2.2.0" />
1212
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
13+
<PackageReference Include="PdfSharp" Version="1.32.3057" />
1314
</ItemGroup>
1415
<ItemGroup>
1516
<Folder Include="Puppeteer\" />
17+
<Folder Include="Page\" />
1618
</ItemGroup>
1719
<ItemGroup>
1820
<ProjectReference Include="..\PuppeteerSharp\PuppeteerSharp.csproj" />
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace PuppeteerSharp.Tests
5+
{
6+
public static class TestConstants
7+
{
8+
public const int HttpsPort = 8908;
9+
public const string ServerUrl = "http://localhost:8907";
10+
public const string HttpsPrefix = "https://localhost:8908";
11+
public const int ChromiumRevision = 526987;
12+
13+
public static readonly Dictionary<string, object> DefaultBrowserOptions = new Dictionary<string, object>()
14+
{
15+
{ "slowMo", Convert.ToInt32(Environment.GetEnvironmentVariable("SLOW_MO") ?? "0") },
16+
{ "headless", Convert.ToBoolean(Environment.GetEnvironmentVariable("HEADLESS") ?? "true") },
17+
{ "args", new[] { "--no-sandbox" }},
18+
{ "timeout", 0}
19+
};
20+
}
21+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace PuppeteerSharp
2+
{
3+
public class MarginOptions
4+
{
5+
public decimal Top { get; set; }
6+
public decimal Left { get; set; }
7+
public decimal Bottom { get; set; }
8+
public decimal Right { get; set; }
9+
}
10+
}

0 commit comments

Comments
 (0)