Skip to content

Commit 27fee8f

Browse files
committed
js: add PrintOptions with predefined and custom sizes; tests (#15072)
1 parent 4fa3952 commit 27fee8f

File tree

2 files changed

+328
-0
lines changed

2 files changed

+328
-0
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
goog.module('webdriver.print_options');
19+
goog.module.declareLegacyNamespace();
20+
21+
22+
/**
23+
* Represents the orientation of the page in the printed document.
24+
* @enum {string}
25+
*/
26+
const PrintOrientation = {
27+
PORTRAIT: 'portrait',
28+
LANDSCAPE: 'landscape'
29+
};
30+
31+
/**
32+
* Represents a page size for printing.
33+
*/
34+
class PageSize {
35+
constructor(width, height) {
36+
if (width <= 0 || height <= 0) {
37+
throw new Error('Page size dimensions must be positive.');
38+
}
39+
this.width = width;
40+
this.height = height;
41+
}
42+
43+
static get A4() {
44+
return new PageSize(21.0, 29.7);
45+
}
46+
47+
static get Letter() {
48+
return new PageSize(21.59, 27.94);
49+
}
50+
51+
static get Legal() {
52+
return new PageSize(21.59, 35.56);
53+
}
54+
55+
static get Tabloid() {
56+
return new PageSize(27.94, 43.18);
57+
}
58+
}
59+
60+
/**
61+
* Represents margins for the printed document.
62+
*/
63+
class Margins {
64+
constructor(top, right, bottom, left) {
65+
if ([top, right, bottom, left].some(value => value < 0)) {
66+
throw new Error('Margins cannot have negative values.');
67+
}
68+
this.top = top;
69+
this.right = right;
70+
this.bottom = bottom;
71+
this.left = left;
72+
}
73+
74+
static get Default() {
75+
return new Margins(1.0, 1.0, 1.0, 1.0);
76+
}
77+
}
78+
79+
80+
81+
/**
82+
* Represents the options to send for printing a page.
83+
*/
84+
class PrintOptions {
85+
/**
86+
* Initializes a new instance of the PrintOptions class.
87+
*/
88+
constructor() {
89+
this.orientation = PrintOrientation.PORTRAIT;
90+
this.scale = 1.0;
91+
this.background = false;
92+
this.shrinkToFit = true;
93+
this.page = PrintOptions.PaperSize.A4;
94+
this.margin = PrintOptions.DefaultMargins;
95+
this.pageRanges = [];
96+
}
97+
98+
/**
99+
* Predefined paper sizes.
100+
*/
101+
static get PaperSize() {
102+
return {
103+
A4: { width: 21.0, height: 29.7 },
104+
LETTER: { width: 21.59, height: 27.94 },
105+
LEGAL: { width: 21.59, height: 35.56 },
106+
TABLOID: { width: 27.94, height: 43.18 }
107+
};
108+
}
109+
110+
/**
111+
* Default margins.
112+
*/
113+
static get DefaultMargins() {
114+
return { top: 1.0, bottom: 1.0, left: 1.0, right: 1.0 };
115+
}
116+
117+
/**
118+
* Sets the orientation of the printed document.
119+
* @param {string} orientation - Must be either "portrait" or "landscape".
120+
*/
121+
setOrientation(orientation) {
122+
if (!Object.values(PrintOrientation).includes(orientation)) {
123+
throw new Error(`Invalid orientation: ${orientation}`);
124+
}
125+
this.orientation = orientation;
126+
}
127+
128+
/**
129+
* Sets the scale factor for the printed document.
130+
* @param {number} scale - Must be between 0.1 and 2.0.
131+
*/
132+
setScale(scale) {
133+
if (scale < 0.1 || scale > 2.0) {
134+
throw new Error('Scale factor must be between 0.1 and 2.0.');
135+
}
136+
this.scale = scale;
137+
}
138+
139+
/**
140+
* Sets the page size for the printed document.
141+
* @param {{ width: number, height: number }} pageSize - The page size object.
142+
*/
143+
setPageSize(pageSize) {
144+
if (!pageSize || pageSize.width <= 0 || pageSize.height <= 0) {
145+
throw new Error('Invalid page size dimensions.');
146+
}
147+
this.page = pageSize;
148+
}
149+
150+
/**
151+
* Sets the margins for the printed document.
152+
* @param {{ top: number, bottom: number, left: number, right: number }} margins - The margins object.
153+
*/
154+
setMargins(margins) {
155+
if (!margins || margins.top < 0 || margins.bottom < 0 || margins.left < 0 || margins.right < 0) {
156+
throw new Error('Margins cannot have negative values.');
157+
}
158+
this.margin = margins;
159+
}
160+
161+
/**
162+
* Adds a range of pages to print.
163+
* @param {string} range - The range in the form "x-y".
164+
*/
165+
addPageRange(range) {
166+
if (!range || !/^\d+(-\d+)?$/.test(range)) {
167+
throw new Error(`Invalid page range: ${range}`);
168+
}
169+
if (this.pageRanges.includes(range)) {
170+
throw new Error(`Page range "${range}" is already added.`);
171+
}
172+
this.pageRanges.push(range);
173+
}
174+
175+
/**
176+
* Serializes the PrintOptions object to JSON for WebDriver.
177+
* @returns {object} The JSON representation of the PrintOptions object.
178+
*/
179+
toDictionary() {
180+
return {
181+
orientation: this.orientation,
182+
scale: this.scale,
183+
page: { width: this.pageSize.width, height: this.pageSize.height },
184+
margin: {
185+
top: this.margins.top,
186+
right: this.margins.right,
187+
bottom: this.margins.bottom,
188+
left: this.margins.left,
189+
},
190+
pageRanges: this.pageRanges,
191+
};
192+
}
193+
}
194+
195+
export { PrintOptions, PrintOrientation, PageSize, Margins };
196+
197+
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
19+
goog.provide('webdriver.PrintOptionsTest');
20+
21+
goog.require('goog.testing.jsunit');
22+
goog.require('webdriver.PrintOptions');
23+
goog.require('webdriver.PrintOrientation');
24+
goog.require('webdriver.PageSize');
25+
goog.require('webdriver.Margins');
26+
27+
goog.require('webdriver.print_options');
28+
29+
/**
30+
* Tests for the PrintOptions class.
31+
*/
32+
function testDefaultPageSize() {
33+
console.log("*******************");
34+
35+
console.log("Running test: should set default page size to A4");
36+
const options = new webdriver.PrintOptions();
37+
assertEquals(
38+
webdriver.PrintOptions.PaperSize.A4.width,
39+
options.page.width
40+
);
41+
assertEquals(
42+
webdriver.PrintOptions.PaperSize.A4.height,
43+
options.page.height
44+
);
45+
}
46+
47+
function testCustomPageSize() {
48+
const options = new webdriver.PrintOptions();
49+
const customSize = { width: 25, height: 30 };
50+
options.setPageSize(customSize);
51+
assertEquals(25, options.page.width);
52+
assertEquals(30, options.page.height);
53+
}
54+
55+
closure_test_suite(
56+
name = "test",
57+
data = [
58+
":all_files",
59+
":deps",
60+
"//javascript/atoms:deps",
61+
"//javascript/webdriver/atoms/inject:deps",
62+
],
63+
)
64+
65+
function testDebugLogging() {
66+
console.log("Running debug logging test...");
67+
fail("Intentional failure to check log output");
68+
}
69+
70+
function testInvalidPageSize() {
71+
const options = new webdriver.PrintOptions();
72+
assertThrows(() => {
73+
options.setPageSize(null);
74+
}, 'Invalid page size dimensions.');
75+
}
76+
77+
function testOrientation() {
78+
const options = new webdriver.PrintOptions();
79+
options.setOrientation(webdriver.PrintOrientation.LANDSCAPE);
80+
assertEquals(webdriver.PrintOrientation.LANDSCAPE, options.orientation);
81+
}
82+
83+
function testCustomMargins() {
84+
const options = new webdriver.PrintOptions();
85+
const customMargins = { top: 1, right: 2, bottom: 3, left: 4 };
86+
options.setMargins(customMargins);
87+
assertEquals(1, options.margin.top);
88+
assertEquals(2, options.margin.right);
89+
assertEquals(3, options.margin.bottom);
90+
assertEquals(4, options.margin.left);
91+
}
92+
93+
function testNegativeMargins() {
94+
const options = new webdriver.PrintOptions();
95+
assertThrows(() => {
96+
options.setMargins({ top: -1, right: 1, bottom: 1, left: 1 });
97+
}, 'Margins cannot have negative values.');
98+
}
99+
100+
function testPageRanges() {
101+
const options = new webdriver.PrintOptions();
102+
options.addPageRange('1-5');
103+
assertEquals('1-5', options.pageRanges.join(','));
104+
}
105+
106+
function testInvalidPageRanges() {
107+
const options = new webdriver.PrintOptions();
108+
assertThrows(() => {
109+
options.addPageRange('1-2-3');
110+
}, 'Invalid page range format.');
111+
}
112+
113+
function testSerialization() {
114+
const options = new webdriver.PrintOptions();
115+
options.setOrientation(webdriver.PrintOrientation.LANDSCAPE);
116+
options.setScale(1.5);
117+
options.setPageSize(webdriver.PrintOptions.PaperSize.LETTER);
118+
options.setMargins({ top: 1, right: 1, bottom: 1, left: 1 });
119+
options.addPageRange('1-5');
120+
121+
const dict = options.toJSON();
122+
assertObjectEquals(dict, {
123+
orientation: 'landscape',
124+
scale: 1.5,
125+
background: false,
126+
shrinkToFit: true,
127+
page: { width: 21.59, height: 27.94 },
128+
margin: { top: 1, right: 1, bottom: 1, left: 1 },
129+
pageRanges: '1-5',
130+
});
131+
}

0 commit comments

Comments
 (0)