mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
11 Commits
v38.8.1
...
v32.0.0-al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e84572a8f | ||
|
|
79751340c6 | ||
|
|
50ea20168d | ||
|
|
38f7beb216 | ||
|
|
d7858f2f91 | ||
|
|
76204e184a | ||
|
|
23b61cf833 | ||
|
|
ff16e0e858 | ||
|
|
a9b0e73492 | ||
|
|
9fc0bfece2 | ||
|
|
efe98f76d1 |
@@ -279,7 +279,7 @@ Aliased to `--debug[=[host:]port`.
|
||||
|
||||
Specify ways of the inspector web socket url exposure.
|
||||
|
||||
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
|
||||
By default inspector websocket url is available in stderr and under /json/list endpoint on `http://host:port/json/list`.
|
||||
|
||||
### `--no-deprecation`
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> Get system preferences.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)
|
||||
|
||||
```js
|
||||
const { systemPreferences } = require('electron')
|
||||
|
||||
@@ -125,7 +125,7 @@ in the form included below:
|
||||
]
|
||||
```
|
||||
|
||||
::: info
|
||||
:::info
|
||||
|
||||
For an implementation example, see [`src/resedit.ts`](https://github.com/electron/packager/blob/main/src/resedit.ts)
|
||||
in the Electron Packager code.
|
||||
|
||||
@@ -23,8 +23,8 @@ and only allow the capabilities you want to support.
|
||||
[we do not recommend you to use WebViews](../api/webview-tag.md#warning),
|
||||
as this tag undergoes dramatic architectural changes that may affect stability
|
||||
of your application. Consider switching to alternatives, like `iframe` and
|
||||
Electron's `BrowserView`, or an architecture that avoids embedded content
|
||||
by design.
|
||||
Electron's [`WebContentsView`](../api/web-contents-view.md), or an architecture
|
||||
that avoids embedded content by design.
|
||||
|
||||
[WebViews](../api/webview-tag.md) are based on Chromium's WebViews and are not
|
||||
explicitly supported by Electron. We do not guarantee that the WebView API will
|
||||
|
||||
@@ -350,6 +350,7 @@ auto_filenames = {
|
||||
|
||||
utility_bundle_deps = [
|
||||
"lib/browser/api/net-fetch.ts",
|
||||
"lib/browser/api/system-preferences.ts",
|
||||
"lib/browser/message-port-main.ts",
|
||||
"lib/common/api/net-client-request.ts",
|
||||
"lib/common/define-properties.ts",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Utility side modules, please sort alphabetically.
|
||||
export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'net', loader: () => require('./net') }
|
||||
{ name: 'net', loader: () => require('./net') },
|
||||
{ name: 'systemPreferences', loader: () => require('@electron/internal/browser/api/system-preferences') }
|
||||
];
|
||||
|
||||
@@ -17,6 +17,14 @@ const { makeRequireFunction } = __non_webpack_require__('internal/modules/helper
|
||||
global.module = new Module('electron/js2c/worker_init');
|
||||
global.require = makeRequireFunction(global.module);
|
||||
|
||||
// See WebWorkerObserver::WorkerScriptReadyForEvaluation.
|
||||
if ((globalThis as any).blinkfetch) {
|
||||
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
|
||||
for (const key of keys) {
|
||||
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
|
||||
}
|
||||
}
|
||||
|
||||
// Set the __filename to the path of html file if it is file: protocol.
|
||||
// NB. 'self' isn't defined in an AudioWorklet.
|
||||
if (typeof self !== 'undefined' && self.location.protocol === 'file:') {
|
||||
|
||||
@@ -129,3 +129,4 @@ feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch
|
||||
fix_font_face_resolution_when_renderer_is_blocked.patch
|
||||
feat_enable_passing_exit_code_on_service_process_crash.patch
|
||||
chore_remove_reference_to_chrome_browser_themes.patch
|
||||
x11_use_localized_display_label_only_for_browser_process.patch
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Mon, 17 Jun 2024 18:05:47 +0000
|
||||
Subject: Use localized display label only for browser process
|
||||
|
||||
With https://crrev.com/c/5098130, GetPrimaryDisplayRefreshIntervalFromXrandr uses BuildDisplaysFromXRandRInfo
|
||||
to calculate the primary display frequency. In software compositing mode --disable-gpu-compositing,
|
||||
this code path will be called from the gpu process via SoftwareOutputSurface::SwapBuffers and
|
||||
can trigger a crash when attempting to set localized string. This is because on linux,
|
||||
gpu process does not have access to the resource bundle.
|
||||
|
||||
Bug: none
|
||||
Change-Id: I9d66b98c07a1a8671369546d4fc685213904a84f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5631219
|
||||
Auto-Submit: Deepak Mohan (Robo) <hop2deep@gmail.com>
|
||||
Reviewed-by: Thomas Anderson <thomasanderson@chromium.org>
|
||||
Reviewed-by: Scott Violet <sky@chromium.org>
|
||||
Commit-Queue: Scott Violet <sky@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1315980}
|
||||
|
||||
diff --git a/ui/base/x/x11_display_util.cc b/ui/base/x/x11_display_util.cc
|
||||
index ffaea4fef9931050f1c1888674bf2f7498c578da..faf59929eb7e291502c449631e54f3841582bd9e 100644
|
||||
--- a/ui/base/x/x11_display_util.cc
|
||||
+++ b/ui/base/x/x11_display_util.cc
|
||||
@@ -299,6 +299,7 @@ std::vector<display::Display> BuildDisplaysFromXRandRInfo(
|
||||
const display::DisplayConfig& display_config,
|
||||
size_t* primary_display_index_out) {
|
||||
DCHECK(primary_display_index_out);
|
||||
+ auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
const float primary_scale = display_config.primary_scale;
|
||||
|
||||
auto* connection = x11::Connection::Get();
|
||||
@@ -348,7 +349,7 @@ std::vector<display::Display> BuildDisplaysFromXRandRInfo(
|
||||
connection->Flush();
|
||||
|
||||
std::vector<x11::Future<x11::GetPropertyReply>> icc_futures{n_iccs};
|
||||
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless)) {
|
||||
+ if (!command_line->HasSwitch(switches::kHeadless)) {
|
||||
for (size_t monitor = 0; monitor < n_iccs; ++monitor) {
|
||||
icc_futures[monitor] = GetIccProfileFuture(connection, monitor);
|
||||
}
|
||||
@@ -446,11 +447,18 @@ std::vector<display::Display> BuildDisplaysFromXRandRInfo(
|
||||
}
|
||||
|
||||
const std::string name(output_info->name.begin(), output_info->name.end());
|
||||
+ auto process_type =
|
||||
+ command_line->GetSwitchValueASCII("type");
|
||||
if (base::StartsWith(name, "eDP") || base::StartsWith(name, "LVDS")) {
|
||||
display::SetInternalDisplayIds({display_id});
|
||||
- // Use localized variant of "Built-in display" for internal displays.
|
||||
+ // For browser process which has access to resource bundle,
|
||||
+ // use localized variant of "Built-in display" for internal displays.
|
||||
// This follows the ozone DRM behavior (i.e. ChromeOS).
|
||||
- display.set_label(l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL));
|
||||
+ if (process_type.empty()) {
|
||||
+ display.set_label(l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL));
|
||||
+ } else {
|
||||
+ display.set_label("Built-in display");
|
||||
+ }
|
||||
} else {
|
||||
display.set_label(edid_parser.display_name());
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import contextlib
|
||||
import errno
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -184,13 +185,16 @@ def get_electron_exec():
|
||||
|
||||
def get_buildtools_executable(name):
|
||||
buildtools = os.path.realpath(os.path.join(ELECTRON_DIR, '..', 'buildtools'))
|
||||
chromium_platform = {
|
||||
'darwin': 'mac',
|
||||
'linux': 'linux64',
|
||||
'linux2': 'linux64',
|
||||
'win32': 'win',
|
||||
'cygwin': 'win',
|
||||
}[sys.platform]
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
chromium_platform = 'mac_arm64' if platform.machine() == 'arm64' else 'mac'
|
||||
elif sys.platform in ['win32', 'cygwin']:
|
||||
chromium_platform = 'win'
|
||||
elif sys.platform in ['linux', 'linux2']:
|
||||
chromium_platform = 'linux64'
|
||||
else:
|
||||
raise Exception(f"Unsupported platform: {sys.platform}")
|
||||
|
||||
if name == 'clang-format':
|
||||
path = os.path.join(buildtools, chromium_platform, 'format', name)
|
||||
else:
|
||||
|
||||
@@ -385,6 +385,7 @@ function buildCircleCI (targetBranch, options) {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function buildGHActions (targetBranch, options) {
|
||||
if (options.job) {
|
||||
assert(ghActionsPublishWorkflows.includes(options.job), `Unknown GitHub Actions workflow name: ${options.job}. Valid values are: ${ghActionsPublishWorkflows}.`);
|
||||
@@ -405,10 +406,10 @@ function runRelease (targetBranch, options) {
|
||||
buildCircleCI(targetBranch, options);
|
||||
break;
|
||||
}
|
||||
case 'GitHubActions': {
|
||||
buildGHActions(targetBranch, options);
|
||||
break;
|
||||
}
|
||||
// case 'GitHubActions': {
|
||||
// buildGHActions(targetBranch, options);
|
||||
// break;
|
||||
// }
|
||||
case 'AppVeyor': {
|
||||
buildAppVeyor(targetBranch, options);
|
||||
break;
|
||||
@@ -421,7 +422,7 @@ function runRelease (targetBranch, options) {
|
||||
} else {
|
||||
buildCircleCI(targetBranch, options);
|
||||
buildAppVeyor(targetBranch, options);
|
||||
buildGHActions(targetBranch, options);
|
||||
// buildGHActions(targetBranch, options);
|
||||
}
|
||||
console.log(`${jobRequestedCount} jobs were requested.`);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,8 @@ std::string SystemPreferences::GetMediaAccessStatus(
|
||||
}
|
||||
|
||||
void SystemPreferences::InitializeWindow() {
|
||||
if (electron::IsUtilityProcess())
|
||||
return;
|
||||
// Wait until app is ready before creating sys color listener
|
||||
// Creating this listener before the app is ready causes global shortcuts
|
||||
// to not fire
|
||||
|
||||
@@ -76,8 +76,11 @@ void MessagePort::PostMessage(gin::Arguments* args) {
|
||||
return;
|
||||
}
|
||||
|
||||
electron::SerializeV8Value(args->isolate(), message_value,
|
||||
&transferable_message);
|
||||
if (!electron::SerializeV8Value(args->isolate(), message_value,
|
||||
&transferable_message)) {
|
||||
// SerializeV8Value sets an exception.
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> transferables;
|
||||
std::vector<gin::Handle<MessagePort>> wrapped_ports;
|
||||
|
||||
@@ -100,9 +100,10 @@
|
||||
V(electron_renderer_ipc) \
|
||||
V(electron_renderer_web_frame)
|
||||
|
||||
#define ELECTRON_UTILITY_BINDINGS(V) \
|
||||
V(electron_browser_event_emitter) \
|
||||
V(electron_common_net) \
|
||||
#define ELECTRON_UTILITY_BINDINGS(V) \
|
||||
V(electron_browser_event_emitter) \
|
||||
V(electron_browser_system_preferences) \
|
||||
V(electron_common_net) \
|
||||
V(electron_utility_parent_port)
|
||||
|
||||
#define ELECTRON_TESTING_BINDINGS(V) V(electron_common_testing)
|
||||
|
||||
@@ -111,7 +111,7 @@ std::string GetLaunchStringForError(NSError* error) {
|
||||
return "The specified path doesn't exist or the helper tool at the "
|
||||
"specified path isn't valid";
|
||||
default:
|
||||
return "Failed to register the login item";
|
||||
return base::SysNSStringToUTF8([error localizedDescription]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,9 +66,25 @@ void WebWorkerObserver::WorkerScriptReadyForEvaluation(
|
||||
std::shared_ptr<node::Environment> env =
|
||||
node_bindings_->CreateEnvironment(worker_context, nullptr);
|
||||
|
||||
// We need to use the Blink implementation of fetch in web workers
|
||||
// Node.js deletes the global fetch function when their fetch implementation
|
||||
// is disabled, so we need to save and re-add it after the Node.js environment
|
||||
// is loaded. See corresponding change in node/init.ts.
|
||||
v8::Local<v8::Object> global = worker_context->Global();
|
||||
v8::Local<v8::String> fetch_string = gin::StringToV8(env->isolate(), "fetch");
|
||||
v8::MaybeLocal<v8::Value> fetch = global->Get(worker_context, fetch_string);
|
||||
|
||||
std::vector<std::string> keys = {"fetch", "Response", "FormData", "Request",
|
||||
"Headers"};
|
||||
for (const auto& key : keys) {
|
||||
v8::MaybeLocal<v8::Value> value =
|
||||
global->Get(worker_context, gin::StringToV8(isolate, key.c_str()));
|
||||
if (!value.IsEmpty()) {
|
||||
std::string blink_key = "blink" + key;
|
||||
global
|
||||
->Set(worker_context, gin::StringToV8(isolate, blink_key.c_str()),
|
||||
value.ToLocalChecked())
|
||||
.Check();
|
||||
}
|
||||
}
|
||||
|
||||
// Add Electron extended APIs.
|
||||
electron_bindings_->BindTo(env->isolate(), env->process_object());
|
||||
@@ -76,16 +92,6 @@ void WebWorkerObserver::WorkerScriptReadyForEvaluation(
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(env.get());
|
||||
|
||||
// We need to use the Blink implementation of fetch in WebWorker process
|
||||
// Node.js deletes the global fetch function when their fetch implementation
|
||||
// is disabled, so we need to save and re-add it after the Node.js environment
|
||||
// is loaded.
|
||||
if (!fetch.IsEmpty()) {
|
||||
worker_context->Global()
|
||||
->Set(worker_context, fetch_string, fetch.ToLocalChecked())
|
||||
.Check();
|
||||
}
|
||||
|
||||
// Make uv loop being wrapped by window context.
|
||||
node_bindings_->set_uv_env(env.get());
|
||||
|
||||
|
||||
@@ -44,7 +44,13 @@ void ParentPort::PostMessage(v8::Local<v8::Value> message_value) {
|
||||
if (!connector_closed_ && connector_ && connector_->is_valid()) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
blink::TransferableMessage transferable_message;
|
||||
electron::SerializeV8Value(isolate, message_value, &transferable_message);
|
||||
|
||||
if (!electron::SerializeV8Value(isolate, message_value,
|
||||
&transferable_message)) {
|
||||
// SerializeV8Value sets an exception.
|
||||
return;
|
||||
}
|
||||
|
||||
mojo::Message mojo_message =
|
||||
blink::mojom::TransferableMessage::WrapAsMessage(
|
||||
std::move(transferable_message));
|
||||
|
||||
@@ -25,7 +25,12 @@ ifdescribe(!(['arm', 'arm64'].includes(process.arch)) || (process.platform !== '
|
||||
});
|
||||
|
||||
describe('startRecording', function () {
|
||||
this.timeout(5e3);
|
||||
if (process.platform === 'win32' && process.arch === 'arm64') {
|
||||
// WOA needs more time
|
||||
this.timeout(10e3);
|
||||
} else {
|
||||
this.timeout(5e3);
|
||||
}
|
||||
|
||||
const getFileSizeInKiloBytes = (filePath: string) => {
|
||||
const stats = fs.statSync(filePath);
|
||||
@@ -84,7 +89,12 @@ ifdescribe(!(['arm', 'arm64'].includes(process.arch)) || (process.platform !== '
|
||||
});
|
||||
|
||||
describe('stopRecording', function () {
|
||||
this.timeout(5e3);
|
||||
if (process.platform === 'win32' && process.arch === 'arm64') {
|
||||
// WOA needs more time
|
||||
this.timeout(10e3);
|
||||
} else {
|
||||
this.timeout(5e3);
|
||||
}
|
||||
|
||||
it('does not crash on empty string', async () => {
|
||||
const options = {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { closeWindow } from './lib/window-helpers';
|
||||
import { once } from 'node:events';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { setImmediate } from 'node:timers/promises';
|
||||
import { systemPreferences } from 'electron';
|
||||
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures', 'api', 'utility-process');
|
||||
const isWindowsOnArm = process.platform === 'win32' && process.arch === 'arm64';
|
||||
@@ -297,6 +298,17 @@ describe('utilityProcess module', () => {
|
||||
expect(child.kill()).to.be.true();
|
||||
await exit;
|
||||
});
|
||||
|
||||
it('handles the parent port trying to send an non-clonable object', async () => {
|
||||
const child = utilityProcess.fork(path.join(fixturesPath, 'non-cloneable.js'));
|
||||
await once(child, 'spawn');
|
||||
child.postMessage('non-cloneable');
|
||||
const [data] = await once(child, 'message');
|
||||
expect(data).to.equal('caught-non-cloneable');
|
||||
const exit = once(child, 'exit');
|
||||
expect(child.kill()).to.be.true();
|
||||
await exit;
|
||||
});
|
||||
});
|
||||
|
||||
describe('behavior', () => {
|
||||
@@ -393,6 +405,18 @@ describe('utilityProcess module', () => {
|
||||
expect(output).to.include(result);
|
||||
});
|
||||
|
||||
ifit(process.platform !== 'linux')('can access exposed main process modules from the utility process', async () => {
|
||||
const message = 'Message from utility process';
|
||||
const child = utilityProcess.fork(path.join(fixturesPath, 'expose-main-process-module.js'));
|
||||
await once(child, 'spawn');
|
||||
child.postMessage(message);
|
||||
const [data] = await once(child, 'message');
|
||||
expect(data).to.equal(systemPreferences.getMediaAccessStatus('screen'));
|
||||
const exit = once(child, 'exit');
|
||||
expect(child.kill()).to.be.true();
|
||||
await exit;
|
||||
});
|
||||
|
||||
it('can establish communication channel with sandboxed renderer', async () => {
|
||||
const result = 'Message from sandboxed renderer';
|
||||
const w = new BrowserWindow({
|
||||
|
||||
@@ -1019,12 +1019,35 @@ describe('chromium features', () => {
|
||||
});
|
||||
|
||||
it('Worker has node integration with nodeIntegrationInWorker', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, nodeIntegrationInWorker: true, contextIsolation: false } });
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
nodeIntegrationInWorker: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
|
||||
w.loadURL(`file://${fixturesPath}/pages/worker.html`);
|
||||
const [, data] = await once(ipcMain, 'worker-result');
|
||||
expect(data).to.equal('object function object function');
|
||||
});
|
||||
|
||||
it('Worker has access to fetch-dependent interfaces with nodeIntegrationInWorker', async () => {
|
||||
const w = new BrowserWindow({
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
nodeIntegrationInWorker: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
|
||||
w.loadURL(`file://${fixturesPath}/pages/worker-fetch.html`);
|
||||
const [, data] = await once(ipcMain, 'worker-fetch-result');
|
||||
expect(data).to.equal('function function function function function');
|
||||
});
|
||||
|
||||
describe('SharedWorker', () => {
|
||||
it('can work', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
|
||||
6
spec/fixtures/api/utility-process/expose-main-process-module.js
vendored
Normal file
6
spec/fixtures/api/utility-process/expose-main-process-module.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
const { systemPreferences } = require('electron');
|
||||
|
||||
const status = systemPreferences.getMediaAccessStatus('screen');
|
||||
process.parentPort.on('message', () => {
|
||||
process.parentPort.postMessage(status);
|
||||
});
|
||||
11
spec/fixtures/api/utility-process/non-cloneable.js
vendored
Normal file
11
spec/fixtures/api/utility-process/non-cloneable.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
const nonClonableObject = () => {};
|
||||
|
||||
process.parentPort.on('message', () => {
|
||||
try {
|
||||
process.parentPort.postMessage(nonClonableObject);
|
||||
} catch (error) {
|
||||
if (/An object could not be cloned/.test(error.message)) {
|
||||
process.parentPort.postMessage('caught-non-cloneable');
|
||||
}
|
||||
}
|
||||
});
|
||||
12
spec/fixtures/pages/worker-fetch.html
vendored
Normal file
12
spec/fixtures/pages/worker-fetch.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
const { ipcRenderer } = require('electron')
|
||||
let worker = new Worker(`../workers/worker_node_fetch.js`)
|
||||
worker.onmessage = function (event) {
|
||||
ipcRenderer.send('worker-fetch-result', event.data)
|
||||
worker.terminate()
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
7
spec/fixtures/workers/worker_node_fetch.js
vendored
Normal file
7
spec/fixtures/workers/worker_node_fetch.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
self.postMessage([
|
||||
typeof fetch,
|
||||
typeof Response,
|
||||
typeof Request,
|
||||
typeof Headers,
|
||||
typeof FormData
|
||||
].join(' '));
|
||||
@@ -159,6 +159,38 @@ describe('node feature', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetch', () => {
|
||||
itremote('works correctly when nodeIntegration is enabled in the renderer', async (fixtures: string) => {
|
||||
const file = require('node:path').join(fixtures, 'hello.txt');
|
||||
expect(() => {
|
||||
fetch('file://' + file);
|
||||
}).to.not.throw();
|
||||
|
||||
expect(() => {
|
||||
const formData = new FormData();
|
||||
formData.append('username', 'Groucho');
|
||||
}).not.to.throw();
|
||||
|
||||
expect(() => {
|
||||
const request = new Request('https://example.com', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ foo: 'bar' })
|
||||
});
|
||||
expect(request.method).to.equal('POST');
|
||||
}).not.to.throw();
|
||||
|
||||
expect(() => {
|
||||
const response = new Response('Hello, world!');
|
||||
expect(response.status).to.equal(200);
|
||||
}).not.to.throw();
|
||||
|
||||
expect(() => {
|
||||
const headers = new Headers();
|
||||
headers.append('Content-Type', 'text/xml');
|
||||
}).not.to.throw();
|
||||
}, [fixtures]);
|
||||
});
|
||||
|
||||
it('does not hang when using the fs module in the renderer process', async () => {
|
||||
const appPath = path.join(mainFixturesPath, 'apps', 'libuv-hang', 'main.js');
|
||||
const appProcess = childProcess.spawn(process.execPath, [appPath], {
|
||||
|
||||
Reference in New Issue
Block a user