Skip to content

Commit 2885f92

Browse files
committed
fix: disposing of tabs & targets
1 parent 78d3aad commit 2885f92

File tree

2 files changed

+57
-26
lines changed

2 files changed

+57
-26
lines changed

__tests__/unit/chrome.spec.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,17 @@ describe('chrome', () => {
2121
});
2222

2323
it('should able to open a tab', async () => {
24-
return Promise.using(chrome.openTab(), async ({ Page }) => {
25-
await Page.navigate({ url });
26-
await Page.loadEventFired();
27-
28-
// TODO: check page contents
29-
});
24+
const tab = await chrome.openTab();
25+
const { client: { Page } } = tab;
26+
27+
try {
28+
await Promise.all([
29+
Page.navigate({ url }),
30+
Page.loadEventFired(),
31+
]);
32+
} finally {
33+
await Chrome.disposer(tab.target, tab.client);
34+
}
3035
});
3136

3237
it('should able to render a pdf', async () => {

src/utils/chrome.js

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ class Chrome {
5555
}, restOpts);
5656

5757
// use custom logger if provided
58-
this.log = logger || debug;
58+
this.log = logger || {
59+
info: (...args) => debug('[info]', ...args),
60+
debug: (...args) => debug('[debug]', ...args),
61+
};
62+
5963
this.onLog = params => this.log.info(params.message.text);
6064
this.timeout = timeout;
6165

@@ -149,26 +153,44 @@ class Chrome {
149153
return this.status(1);
150154
}
151155

156+
/**
157+
* Disposer for assosiated tab/client
158+
* @param {Target} target
159+
* @param {ChromeRemote} client
160+
* @return {Promise}
161+
*/
162+
static async disposer(target, client) {
163+
if (target) await ChromeRemote.Close({ id: target.id }).catch(noop);
164+
if (client) await client.close().catch(noop);
165+
}
166+
152167
/**
153168
* Opens a new Chrome tab
154169
* @return {Promise<ChromeDebugProtocol>}
155170
*/
156171
async openTab() {
157172
await this.waitForStart();
158173

159-
return Promise
160-
.bind(ChromeRemote, this.launcher)
161-
.then(ChromeRemote.New)
162-
.then(target => ChromeRemote({ target, port: this.launcher.port }))
163-
.tap((tab) => {
164-
const { Network, Page, Console } = tab;
174+
let client;
175+
let target;
176+
177+
try {
178+
target = await ChromeRemote.New(this.launcher);
179+
this.log.debug({ target }, 'opened new target');
180+
client = await ChromeRemote({ target, port: this.launcher.port });
165181

166-
Console.messageAdded(this.onLog);
182+
const { Network, Page, Console } = client;
183+
Console.messageAdded(this.onLog);
167184

168-
return Promise.all([Page.enable(), Network.enable()]);
169-
})
170-
.timeout(this.timeout)
171-
.disposer(tab => tab.close().catch(noop));
185+
await Promise
186+
.all([Page.enable(), Network.enable()])
187+
.timeout(this.timeout);
188+
} catch (e) {
189+
Chrome.disposer(target, client);
190+
throw e;
191+
}
192+
193+
return { target, client };
172194
}
173195

174196
/**
@@ -177,22 +199,26 @@ class Chrome {
177199
* @param {Object} opts page printing options
178200
* @return {Promise<String>} base64 encoded PDF document
179201
*/
180-
printToPdf(html, opts = {}) {
181-
return Promise.using(this.openTab(), ({ Page }) => {
202+
async printToPdf(html, opts = {}) {
203+
let tab;
204+
try {
205+
tab = await this.openTab();
206+
const { client: { Page } } = tab;
207+
182208
const url = /^(https?|file|data):/i.test(html)
183209
? html
184210
: `data:text/html;charset=utf-8;base64,${encode(Buffer.from(html))}`;
185211

186-
return Promise
187-
.all([
188-
Page.loadEventFired(),
189-
Page.navigate({ url }),
190-
])
212+
return await Promise
213+
.all([Page.loadEventFired(), Page.navigate({ url })])
191214
.return(Page)
192215
.call('printToPDF', opts)
193216
.get('data')
194217
.timeout(this.timeout);
195-
});
218+
} finally {
219+
// schedules in the "background", no await is needed
220+
Chrome.disposer(tab.target, tab.client);
221+
}
196222
}
197223
}
198224

0 commit comments

Comments
 (0)