Merge remote-tracking branch 'origin/master' into roller/chromium-ad1b791122c04bd91b825fbfbdf1ff4da82a0edb-1558011686736

This commit is contained in:
Jeremy Apthorp 2019-05-21 10:07:17 -07:00
commit ca283c74c9
64 changed files with 2026 additions and 3216 deletions

20
.github/CODEOWNERS vendored
View file

@ -4,17 +4,27 @@
# https://git-scm.com/docs/gitignore
# Most stuff in here is owned by the Community & Safety WG...
/.github/* @electron/wg-community
/.github/* @electron/wg-community
# ...except the Admin WG maintains this file.
/.github/CODEOWNERS @electron/wg-admin
/.github/CODEOWNERS @electron/wg-admin
# Upgrades WG
/patches/ @electron/wg-upgrades
/patches/ @electron/wg-upgrades
# Docs & Tooling WG
/default_app/ @electron/wg-docs-tools
/docs/ @electron/wg-docs-tools
/docs/ @electron/wg-docs-tools
# Releases WG
/npm/ @electron/wg-releases
/npm/ @electron/wg-releases
/script/release-notes @electron/wg-releases
/script/prepare-release.js @electron/wg-releases
/script/bump-version.js @electron/wg-releases
/script/ci-release-build.js @electron/wg-releases
/script/release.js @electron/wg-releases
/script/upload-to-github.js @electron/wg-releases
/script/release-artifact-cleanup.js @electron/wg-releases
/script/get-last-major-for-master.js @electron/wg-releases
/script/find-release.js @electron/wg-releases
/script/download-circleci-artifacts.js @electron/wg-releases

View file

@ -20,7 +20,7 @@ about: Create a report to help us improve Electron
* <!-- (output of `node_modules/.bin/electron --version`) e.g. 4.0.3 -->
* **Operating System:**
* <!-- (Platform and Version) e.g. macOS 10.13.6 / Windows 10 (1803) / Ubuntu 18.04 x64 -->
* **Last Known Working Electron version:**:
* **Last Known Working Electron version:**
* <!-- (if applicable) e.g. 3.1.0 -->
### Expected Behavior

View file

@ -1 +1 @@
6.0.0-nightly.20190404
7.0.0-nightly.20190521

View file

@ -142,7 +142,10 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(DEBUG)
// Print logging to debug.log on Windows
settings.logging_dest = logging::LOG_TO_ALL;
settings.log_file = L"debug.log";
base::FilePath log_filename;
base::PathService::Get(base::DIR_EXE, &log_filename);
log_filename = log_filename.AppendASCII("debug.log");
settings.log_file = log_filename.value().c_str();
settings.lock_log = logging::LOCK_LOG_FILE;
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else

View file

@ -773,6 +773,10 @@ void App::SelectClientCertificate(
}
}
void App::OnGpuInfoUpdate() {
Emit("gpu-info-update");
}
void App::OnGpuProcessCrashed(base::TerminationStatus status) {
Emit("gpu-process-crashed",
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);

View file

@ -157,6 +157,7 @@ class App : public AtomBrowserClient::Delegate,
bool* no_javascript_access) override;
// content::GpuDataManagerObserver:
void OnGpuInfoUpdate() override;
void OnGpuProcessCrashed(base::TerminationStatus status) override;
// content::BrowserChildProcessObserver:

View file

@ -68,7 +68,7 @@ void BrowserView::Init(v8::Isolate* isolate,
const mate::Dictionary& options) {
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
web_preferences.Set("isBrowserView", true);
web_preferences.Set("type", "browserView");
mate::Handle<class WebContents> web_contents =
WebContents::Create(isolate, web_preferences);

View file

@ -297,20 +297,12 @@ WebContents::WebContents(v8::Isolate* isolate,
// Read options.
options.Get("backgroundThrottling", &background_throttling_);
// FIXME(zcbenz): We should read "type" parameter for better design, but
// on Windows we have encountered a compiler bug that if we read "type"
// from |options| and then set |type_|, a memory corruption will happen
// and Electron will soon crash.
// Remvoe this after we upgraded to use VS 2015 Update 3.
// Get type
options.Get("type", &type_);
bool b = false;
if (options.Get("isGuest", &b) && b)
type_ = Type::WEB_VIEW;
else if (options.Get("isBackgroundPage", &b) && b)
type_ = Type::BACKGROUND_PAGE;
else if (options.Get("isBrowserView", &b) && b)
type_ = Type::BROWSER_VIEW;
#if BUILDFLAG(ENABLE_OSR)
else if (options.Get(options::kOffscreen, &b) && b)
if (options.Get(options::kOffscreen, &b) && b)
type_ = Type::OFF_SCREEN;
#endif
@ -2266,7 +2258,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("startDrag", &WebContents::StartDrag)
.SetMethod("isGuest", &WebContents::IsGuest)
.SetMethod("attachToIframe", &WebContents::AttachToIframe)
.SetMethod("detachFromOuterFrame", &WebContents::DetachFromOuterFrame)
.SetMethod("isOffscreen", &WebContents::IsOffScreen)

View file

@ -28,19 +28,23 @@ enum {
#if defined(OS_LINUX)
DIR_APP_DATA, // Application Data directory under the user profile.
#else
#endif
PATH_END, // End of new paths. Those that follow redirect to base::DIR_*
#if !defined(OS_LINUX)
DIR_APP_DATA = base::DIR_APP_DATA,
#endif
#if defined(OS_POSIX)
DIR_CACHE = base::DIR_CACHE, // Directory where to put cache data.
DIR_CACHE = base::DIR_CACHE // Directory where to put cache data.
#else
DIR_CACHE = base::DIR_APP_DATA,
DIR_CACHE = base::DIR_APP_DATA
#endif
PATH_END
};
static_assert(PATH_START < PATH_END, "invalid PATH boundaries");
} // namespace atom
#endif // ATOM_BROWSER_ATOM_PATHS_H_

View file

@ -5,7 +5,6 @@
#include "atom/browser/native_window_views.h"
#if defined(OS_WIN)
#include <objbase.h>
#include <wrl/client.h>
#endif
@ -62,7 +61,6 @@
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
#include "skia/ext/skia_utils_win.h"
#include "ui/base/win/shell.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/display/win/screen_win.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
@ -473,24 +471,15 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
#endif
}
#if defined(USE_X11)
void NativeWindowViews::Maximize() {
#if defined(OS_WIN)
// For window without WS_THICKFRAME style, we can not call Maximize().
if (!(::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME)) {
restore_bounds_ = GetBounds();
auto display =
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
SetBounds(display.work_area(), false);
return;
}
#endif
if (IsVisible())
widget()->Maximize();
else
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
gfx::Rect());
}
#endif
void NativeWindowViews::Unmaximize() {
#if defined(OS_WIN)

View file

@ -2,14 +2,19 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <dwmapi.h>
#include <shellapi.h>
#include "atom/browser/browser.h"
#include "atom/browser/native_window_views.h"
#include "atom/browser/ui/views/root_view.h"
#include "atom/common/atom_constants.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "ui/base/win/accessibility_misc_utils.h"
#include "ui/display/display.h"
#include "ui/display/win/screen_win.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/widget/native_widget_private.h"
// Must be included after other Windows headers.
#include <UIAutomationCoreApi.h>
@ -138,11 +143,155 @@ bool IsScreenReaderActive() {
return screenReader && UiaClientsAreListening();
}
// We use "enum" instead of "enum class" because we need to do bitwise compare.
enum AppbarAutohideEdge {
TOP = 1 << 0,
LEFT = 1 << 1,
BOTTOM = 1 << 2,
RIGHT = 1 << 3,
};
// The thickness of an auto-hide taskbar in pixel.
constexpr int kAutoHideTaskbarThicknessPx = 2;
// Code is copied from chrome_views_delegate_win.cc.
bool MonitorHasAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) {
APPBARDATA taskbar_data = {sizeof(APPBARDATA), NULL, 0, edge};
taskbar_data.hWnd = ::GetForegroundWindow();
// MSDN documents an ABM_GETAUTOHIDEBAREX, which supposedly takes a monitor
// rect and returns autohide bars on that monitor. This sounds like a good
// idea for multi-monitor systems. Unfortunately, it appears to not work at
// least some of the time (erroneously returning NULL) and there's almost no
// online documentation or other sample code using it that suggests ways to
// address this problem. We do the following:-
// 1. Use the ABM_GETAUTOHIDEBAR message. If it works, i.e. returns a valid
// window we are done.
// 2. If the ABM_GETAUTOHIDEBAR message does not work we query the auto hide
// state of the taskbar and then retrieve its position. That call returns
// the edge on which the taskbar is present. If it matches the edge we
// are looking for, we are done.
// NOTE: This call spins a nested run loop.
HWND taskbar = reinterpret_cast<HWND>(
SHAppBarMessage(ABM_GETAUTOHIDEBAR, &taskbar_data));
if (!::IsWindow(taskbar)) {
APPBARDATA taskbar_data = {sizeof(APPBARDATA), 0, 0, 0};
unsigned int taskbar_state = SHAppBarMessage(ABM_GETSTATE, &taskbar_data);
if (!(taskbar_state & ABS_AUTOHIDE))
return false;
taskbar_data.hWnd = ::FindWindow(L"Shell_TrayWnd", NULL);
if (!::IsWindow(taskbar_data.hWnd))
return false;
SHAppBarMessage(ABM_GETTASKBARPOS, &taskbar_data);
if (taskbar_data.uEdge == edge)
taskbar = taskbar_data.hWnd;
}
// There is a potential race condition here:
// 1. A maximized chrome window is fullscreened.
// 2. It is switched back to maximized.
// 3. In the process the window gets a WM_NCCACLSIZE message which calls us to
// get the autohide state.
// 4. The worker thread is invoked. It calls the API to get the autohide
// state. On Windows versions earlier than Windows 7, taskbars could
// easily be always on top or not.
// This meant that we only want to look for taskbars which have the topmost
// bit set. However this causes problems in cases where the window on the
// main thread is still in the process of switching away from fullscreen.
// In this case the taskbar might not yet have the topmost bit set.
// 5. The main thread resumes and does not leave space for the taskbar and
// hence it does not pop when hovered.
//
// To address point 4 above, it is best to not check for the WS_EX_TOPMOST
// window style on the taskbar, as starting from Windows 7, the topmost
// style is always set. We don't support XP and Vista anymore.
if (::IsWindow(taskbar)) {
if (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor)
return true;
// In some cases like when the autohide taskbar is on the left of the
// secondary monitor, the MonitorFromWindow call above fails to return the
// correct monitor the taskbar is on. We fallback to MonitorFromPoint for
// the cursor position in that case, which seems to work well.
POINT cursor_pos = {0};
GetCursorPos(&cursor_pos);
if (MonitorFromPoint(cursor_pos, MONITOR_DEFAULTTONEAREST) == monitor)
return true;
}
return false;
}
int GetAppbarAutohideEdges(HWND hwnd) {
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
if (!monitor)
return 0;
int edges = 0;
if (MonitorHasAutohideTaskbarForEdge(ABE_LEFT, monitor))
edges |= AppbarAutohideEdge::LEFT;
if (MonitorHasAutohideTaskbarForEdge(ABE_TOP, monitor))
edges |= AppbarAutohideEdge::TOP;
if (MonitorHasAutohideTaskbarForEdge(ABE_RIGHT, monitor))
edges |= AppbarAutohideEdge::RIGHT;
if (MonitorHasAutohideTaskbarForEdge(ABE_BOTTOM, monitor))
edges |= AppbarAutohideEdge::BOTTOM;
return edges;
}
} // namespace
std::set<NativeWindowViews*> NativeWindowViews::forwarding_windows_;
HHOOK NativeWindowViews::mouse_hook_ = NULL;
void NativeWindowViews::Maximize() {
int autohide_edges = 0;
if (!has_frame())
autohide_edges = GetAppbarAutohideEdges(GetAcceleratedWidget());
// Only use Maximize() when:
// 1. window has WS_THICKFRAME style;
// 2. and window is not frameless when there is autohide taskbar.
if ((::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME) &&
(has_frame() || autohide_edges == 0)) {
if (IsVisible())
widget()->Maximize();
else
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
gfx::Rect());
return;
}
gfx::Insets insets;
if (!has_frame()) {
// When taskbar is autohide, we need to leave some space so the window
// isn't treated as a "fullscreen app", which would cause the taskbars
// to disappear.
//
// This trick comes from hwnd_message_handler.cc. While Chromium already
// does this for normal window, somehow it is not applying the trick when
// using frameless window, and we have to do it ourselves.
float scale_factor =
display::win::ScreenWin::GetScaleFactorForHWND(GetAcceleratedWidget());
int thickness = std::ceil(kAutoHideTaskbarThicknessPx / scale_factor);
if (autohide_edges & AppbarAutohideEdge::LEFT)
insets.set_left(-thickness);
if (autohide_edges & AppbarAutohideEdge::TOP)
insets.set_top(-thickness);
if (autohide_edges & AppbarAutohideEdge::RIGHT)
insets.set_right(thickness);
if (autohide_edges & AppbarAutohideEdge::BOTTOM)
insets.set_bottom(thickness);
}
restore_bounds_ = GetBounds();
auto display =
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
gfx::Rect bounds = display.work_area();
bounds.Inset(insets);
SetBounds(bounds, false);
}
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
std::string command = AppCommandToString(command_id);
NotifyWindowExecuteAppCommand(command);

View file

@ -17,9 +17,9 @@
<key>CFBundleIconFile</key>
<string>electron.icns</string>
<key>CFBundleVersion</key>
<string>6.0.0-nightly.20190404</string>
<string>7.0.0-nightly.20190521</string>
<key>CFBundleShortVersionString</key>
<string>6.0.0-nightly.20190404</string>
<string>7.0.0-nightly.20190521</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>

View file

@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 6,0,0,20190404
PRODUCTVERSION 6,0,0,20190404
FILEVERSION 7,0,0,20190521
PRODUCTVERSION 7,0,0,20190521
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "6.0.0"
VALUE "FileVersion", "7.0.0"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "6.0.0"
VALUE "ProductVersion", "7.0.0"
VALUE "SquirrelAwareVersion", "1"
END
END

View file

@ -117,7 +117,7 @@ void RunSaveDialogInNewThread(const RunState& run_state,
bool result = ShowSaveDialogSync(settings, &path);
run_state.ui_task_runner->PostTask(
FROM_HERE,
base::BindOnce(&OnSaveDialogDone, std::move(promise), result, path));
base::BindOnce(&OnSaveDialogDone, std::move(promise), !result, path));
run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread);
}
@ -321,7 +321,7 @@ void ShowSaveDialog(const DialogSettings& settings,
RunState run_state;
if (!CreateDialogThread(&run_state)) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate());
dict.Set("canceled", false);
dict.Set("canceled", true);
dict.Set("filePath", base::FilePath());
promise.Resolve(dict.GetHandle());
} else {

View file

@ -108,8 +108,8 @@ WebContentsPreferences::WebContentsPreferences(
mate::Dictionary copied(isolate, web_preferences.GetHandle()->Clone());
// Following fields should not be stored.
copied.Delete("embedder");
copied.Delete("isGuest");
copied.Delete("session");
copied.Delete("type");
mate::ConvertFromV8(isolate, copied.GetHandle(), &preference_);
web_contents->SetUserData(UserDataKey(), base::WrapUnique(this));

View file

@ -35,7 +35,8 @@ using blink::mojom::FileChooserParams;
namespace {
class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
public content::WebContentsObserver {
public content::WebContentsObserver,
public atom::DirectoryListerHelperDelegate {
public:
FileSelectHelper(content::RenderFrameHost* render_frame_host,
std::unique_ptr<content::FileSelectListener> listener,
@ -71,23 +72,61 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
isolate, base::Bind(&FileSelectHelper::OnSaveDialogDone, this)))));
}
void OnDirectoryListerDone(std::vector<FileChooserFileInfoPtr> file_info,
base::FilePath base_dir) override {
OnFilesSelected(std::move(file_info), base_dir);
Release();
}
private:
friend class base::RefCounted<FileSelectHelper>;
~FileSelectHelper() override {}
void EnumerateDirectory(base::FilePath base_dir) {
auto* lister = new net::DirectoryLister(
base_dir, net::DirectoryLister::NO_SORT_RECURSIVE,
new atom::DirectoryListerHelper(base_dir, this));
lister->Start();
// It is difficult for callers to know how long to keep a reference to
// this instance. We AddRef() here to keep the instance alive after we
// return to the caller. Once the directory lister is complete we
// Release() in OnDirectoryListerDone() and at that point we run
// OnFilesSelected() which will deref the last reference held by the
// listener.
AddRef();
}
void OnOpenDialogDone(mate::Dictionary result) {
std::vector<FileChooserFileInfoPtr> file_info;
bool canceled = true;
result.Get("canceled", &canceled);
base::FilePath base_dir;
// For certain file chooser modes (kUploadFolder) we need to do some async
// work before calling back to the listener. In that particular case the
// listener is called from the directory enumerator.
bool ready_to_call_listener = false;
if (!canceled) {
std::vector<base::FilePath> paths;
if (result.Get("filePaths", &paths)) {
for (auto& path : paths) {
file_info.push_back(FileChooserFileInfo::NewNativeFile(
blink::mojom::NativeFileInfo::New(
path, path.BaseName().AsUTF16Unsafe())));
// If we are uploading a folder we need to enumerate its contents
if (mode_ == FileChooserParams::Mode::kUploadFolder &&
paths.size() >= 1) {
base_dir = paths[0];
// Actually enumerate soemwhere off-thread
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&FileSelectHelper::EnumerateDirectory,
this, base_dir));
} else {
for (auto& path : paths) {
file_info.push_back(FileChooserFileInfo::NewNativeFile(
blink::mojom::NativeFileInfo::New(
path, path.BaseName().AsUTF16Unsafe())));
}
ready_to_call_listener = true;
}
if (render_frame_host_ && !paths.empty()) {
@ -98,7 +137,9 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
}
}
}
OnFilesSelected(std::move(file_info));
if (ready_to_call_listener)
OnFilesSelected(std::move(file_info), base_dir);
}
void OnSaveDialogDone(mate::Dictionary result) {
@ -114,12 +155,13 @@ class FileSelectHelper : public base::RefCounted<FileSelectHelper>,
path, path.BaseName().AsUTF16Unsafe())));
}
}
OnFilesSelected(std::move(file_info));
OnFilesSelected(std::move(file_info), base::FilePath());
}
void OnFilesSelected(std::vector<FileChooserFileInfoPtr> file_info) {
void OnFilesSelected(std::vector<FileChooserFileInfoPtr> file_info,
base::FilePath base_dir) {
if (listener_) {
listener_->FileSelected(std::move(file_info), base::FilePath(), mode_);
listener_->FileSelected(std::move(file_info), base_dir, mode_);
listener_.reset();
}
render_frame_host_ = nullptr;
@ -216,6 +258,30 @@ file_dialog::Filters GetFileTypesFromAcceptType(
namespace atom {
DirectoryListerHelper::DirectoryListerHelper(
base::FilePath base,
DirectoryListerHelperDelegate* helper)
: base_dir_(base), delegate_(helper) {}
DirectoryListerHelper::~DirectoryListerHelper() {}
void DirectoryListerHelper::OnListFile(
const net::DirectoryLister::DirectoryListerData& data) {
// We don't want to return directory paths, only file paths
if (data.info.IsDirectory())
return;
paths_.push_back(data.path);
}
void DirectoryListerHelper::OnListDone(int error) {
std::vector<FileChooserFileInfoPtr> file_info;
for (auto path : paths_)
file_info.push_back(FileChooserFileInfo::NewNativeFile(
blink::mojom::NativeFileInfo::New(path, base::string16())));
delegate_->OnDirectoryListerDone(std::move(file_info), base_dir_);
delete this;
}
WebDialogHelper::WebDialogHelper(NativeWindow* window, bool offscreen)
: window_(window), offscreen_(offscreen), weak_factory_(this) {}

View file

@ -6,8 +6,10 @@
#define ATOM_BROWSER_WEB_DIALOG_HELPER_H_
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "net/base/directory_lister.h"
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
namespace base {
@ -22,6 +24,32 @@ class WebContents;
namespace atom {
class DirectoryListerHelperDelegate {
public:
virtual void OnDirectoryListerDone(
std::vector<blink::mojom::FileChooserFileInfoPtr> file_info,
base::FilePath base_dir) = 0;
};
class DirectoryListerHelper
: public net::DirectoryLister::DirectoryListerDelegate {
public:
DirectoryListerHelper(base::FilePath base,
DirectoryListerHelperDelegate* helper);
~DirectoryListerHelper() override;
private:
void OnListFile(
const net::DirectoryLister::DirectoryListerData& data) override;
void OnListDone(int error) override;
base::FilePath base_dir_;
DirectoryListerHelperDelegate* delegate_;
std::vector<base::FilePath> paths_;
DISALLOW_COPY_AND_ASSIGN(DirectoryListerHelper);
};
class NativeWindow;
class WebDialogHelper {

View file

@ -5,11 +5,11 @@
#ifndef ATOM_COMMON_ATOM_VERSION_H_
#define ATOM_COMMON_ATOM_VERSION_H_
#define ATOM_MAJOR_VERSION 6
#define ATOM_MAJOR_VERSION 7
#define ATOM_MINOR_VERSION 0
#define ATOM_PATCH_VERSION 0
// clang-format off
#define ATOM_PRE_RELEASE_VERSION -nightly.20190404
#define ATOM_PRE_RELEASE_VERSION -nightly.20190521
// clang-format on
#ifndef ATOM_STRINGIFY

View file

@ -343,6 +343,10 @@ app.on('login', (event, webContents, request, authInfo, callback) => {
})
```
### Event: 'gpu-info-update'
Emitted whenever there is a GPU info update.
### Event: 'gpu-process-crashed'
Returns:
@ -400,8 +404,10 @@ Returns:
* `workingDirectory` String - The second instance's working directory
This event will be emitted inside the primary instance of your application
when a second instance has been executed. `argv` is an Array of the second instance's
command line arguments, and `workingDirectory` is its current working directory. Usually
when a second instance has been executed and calls `app.requestSingleInstanceLock()`.
`argv` is an Array of the second instance's command line arguments,
and `workingDirectory` is its current working directory. Usually
applications respond to this by making their primary window focused and
non-minimized.
@ -684,7 +690,7 @@ To set the locale, you'll want to use a command line switch at app startup, whic
### `app.getLocaleCountryCode()`
Returns `string` - User operating system's locale two-letter [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) country code. The value is taken from native OS APIs.
Returns `String` - User operating system's locale two-letter [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) country code. The value is taken from native OS APIs.
**Note:** When unable to detect locale country code, it returns empty string.
@ -1012,6 +1018,8 @@ Returns [`ProcessMetric[]`](structures/process-metric.md): Array of `ProcessMetr
Returns [`GPUFeatureStatus`](structures/gpu-feature-status.md) - The Graphics Feature Status from `chrome://gpu/`.
**Note:** This information is only usable after the `gpu-info-update` event is emitted.
### `app.getGPUInfo(infoType)`
* `infoType` String - Values can be either `basic` for basic info or `complete` for complete info.

View file

@ -1,4 +1,4 @@
# API Contract
# Breaking Changes
Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least [one major version](../tutorial/electron-versioning.md#semver) before the change is made.
@ -8,6 +8,16 @@ The `FIXME` string is used in code comments to denote things that should be fixe
## Planned Breaking API Changes (7.0)
### Node Headers URL
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
command line flag when building native Node modules. Both will be supported for
the forseeable future but it is reccomened that you switch.
Deprecated: https://atom.io/download/electron
Replace with: https://electronjs.org/headers
### `session.clearAuthCache(options)`
The `session.clearAuthCache` API no longer accepts options for what to clear, and instead unconditionally clears the whole cache.

View file

@ -592,7 +592,7 @@ win.on('app-command', (e, cmd) => {
})
```
The following app commands are explictly supported on Linux:
The following app commands are explicitly supported on Linux:
* `browser-backward`
* `browser-forward`

View file

@ -10,7 +10,7 @@ Creates a new menu.
### Static Methods
The `menu` class has the following static methods:
The `Menu` class has the following static methods:
#### `Menu.setApplicationMenu(menu)`

View file

@ -177,7 +177,7 @@ Creates a new `NativeImage` instance from `dataURL`.
Returns `NativeImage`
Creates a new `NativeImage` instance from the NSImage that maps to the
given image name. See [`NSImageName`](https://developer.apple.com/documentation/appkit/nsimagename?language=objc)
given image name. See [`System Icons`](https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/system-icons/)
for a list of possible values.
The `hslShift` is applied to the image with the following rules

View file

@ -113,8 +113,8 @@ window.open = customWindowOpen
Important things to notice in the preload script:
- Even though the sandboxed renderer doesn't have Node.js running, it still has
access to a limited node-like environment: `Buffer`, `process`, `setImmediate`
and `require` are available.
access to a limited node-like environment: `Buffer`, `process`, `setImmediate`,
`clearImmediate` and `require` are available.
- The preload script can indirectly access all APIs from the main process through the
`remote` and `ipcRenderer` modules.
- The preload script must be contained in a single script, but it is possible to have
@ -162,16 +162,17 @@ feature. We are still not aware of the security implications of exposing some
Electron renderer APIs to the preload script, but here are some things to
consider before rendering untrusted content:
- A preload script can accidentally leak privileged APIs to untrusted code.
- A preload script can accidentally leak privileged APIs to untrusted code,
unless [`contextIsolation`](../tutorial/security.md#3-enable-context-isolation-for-remote-content)
is also enabled.
- Some bug in V8 engine may allow malicious code to access the renderer preload
APIs, effectively granting full access to the system through the `remote`
module.
module. Therefore, it is highly recommended to
[disable the `remote` module](../tutorial/security.md#15-disable-the-remote-module).
If disabling is not feasible, you should selectively
[filter the `remote` module](../tutorial/security.md#16-filter-the-remote-module).
Since rendering untrusted content in Electron is still uncharted territory,
the APIs exposed to the sandbox preload script should be considered more
unstable than the rest of Electron APIs, and may have breaking changes to fix
security issues.
One planned enhancement that should greatly increase security is to block IPC
messages from sandboxed renderers by default, allowing the main process to
explicitly define a set of messages the renderer is allowed to send.

View file

@ -203,7 +203,7 @@ The `proxyBypassRules` is a comma separated list of rules described below:
* `url` URL
Returns `Promise<string>` - Resolves with the proxy information for `url`.
Returns `Promise<String>` - Resolves with the proxy information for `url`.
#### `ses.setDownloadPath(path)`

View file

@ -55,7 +55,7 @@ export npm_config_target=1.2.3
export npm_config_arch=x64
export npm_config_target_arch=x64
# Download headers for Electron.
export npm_config_disturl=https://atom.io/download/electron
export npm_config_disturl=https://electronjs.org/headers
# Tell node-pre-gyp that we are building for Electron.
export npm_config_runtime=electron
# Tell node-pre-gyp to build module from source code.
@ -72,7 +72,7 @@ use `node-gyp` directly to build for Electron:
```sh
cd /path-to-module/
HOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://atom.io/download/electron
HOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://electronjs.org/headers
```
* `HOME=~/.electron-gyp` changes where to find development headers.

View file

@ -49,7 +49,6 @@ filenames = {
"lib/browser/utils.ts",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/deprecations.js",
"lib/common/api/is-promise.js",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",

View file

@ -47,7 +47,11 @@ const checkAppInitialized = function () {
const saveDialog = (sync, window, options) => {
checkAppInitialized()
if (window && window.constructor !== BrowserWindow) options = window
if (window && window.constructor !== BrowserWindow) {
options = window
window = null
}
if (options == null) options = { title: 'Save' }
const {
@ -74,7 +78,11 @@ const saveDialog = (sync, window, options) => {
const openDialog = (sync, window, options) => {
checkAppInitialized()
if (window && window.constructor !== BrowserWindow) options = window
if (window && window.constructor !== BrowserWindow) {
options = window
window = null
}
if (options == null) {
options = {
title: 'Open',
@ -115,7 +123,11 @@ const openDialog = (sync, window, options) => {
const messageBox = (sync, window, options) => {
checkAppInitialized()
if (window && window.constructor !== BrowserWindow) options = window
if (window && window.constructor !== BrowserWindow) {
options = window
window = null
}
if (options == null) options = { type: 'none' }
const messageBoxTypes = ['none', 'info', 'warning', 'error', 'question']

View file

@ -354,9 +354,6 @@ WebContents.prototype._init = function () {
app.emit('renderer-process-crashed', event, this, ...args)
})
deprecate.event(this, 'did-get-response-details', '-did-get-response-details')
deprecate.event(this, 'did-get-redirect-request', '-did-get-redirect-request')
// The devtools requests the webContents to reload.
this.on('devtools-reload-page', function () {
this.reload()

View file

@ -93,7 +93,7 @@ const startBackgroundPages = function (manifest) {
const contents = webContents.create({
partition: 'persist:__chrome_extension',
isBackgroundPage: true,
type: 'backgroundPage',
sandbox: true,
enableRemoteModule: false
})

View file

@ -59,7 +59,7 @@ const createGuest = function (embedder, params) {
}
const guest = webContents.create({
isGuest: true,
type: 'webview',
partition: params.partition,
embedder: embedder
})

View file

@ -28,7 +28,7 @@ const mergeOptions = function (child, parent, visited) {
visited.add(parent)
for (const key in parent) {
if (key === 'isBrowserView') continue
if (key === 'type') continue
if (!hasProp.call(parent, key)) continue
if (key in child && key !== 'webPreferences') continue
@ -244,7 +244,7 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', functio
options = mergeBrowserWindowOptions(event.sender, options)
event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer)
const { newGuest } = event
if ((event.sender.isGuest() && !event.sender.allowPopups) || event.defaultPrevented) {
if ((event.sender.getType() === 'webview' && !event.sender.allowPopups) || event.defaultPrevented) {
if (newGuest != null) {
if (options.webContents === newGuest.webContents) {
// the webContents is not changed, so set defaultPrevented to false to

View file

@ -1,11 +0,0 @@
'use strict'
const deprecate = require('electron').deprecate
exports.setHandler = function (deprecationHandler) {
deprecate.setHandler(deprecationHandler)
}
exports.getHandler = function () {
return deprecate.getHandler()
}

View file

@ -7,6 +7,5 @@ module.exports = [
{ name: 'shell', file: 'shell' },
// The internal modules, invisible unless you know their names.
{ name: 'deprecate', file: 'deprecate', private: true },
{ name: 'deprecations', file: 'deprecations', private: true },
{ name: 'isPromise', file: 'is-promise', private: true }
]

View file

@ -81,9 +81,7 @@ class LocationProxy {
// It's right, that's bad, but we're doing it anway.
(guestURL as any)[propertyKey] = newVal
return this.ipcRenderer.sendSync(
'ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC',
this.guestId, 'loadURL', guestURL.toString())
return this._invokeWebContentsMethodSync('loadURL', guestURL.toString())
}
}
})
@ -102,7 +100,7 @@ class LocationProxy {
}
private getGuestURL (): URL | null {
const urlString = ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'getURL')
const urlString = this._invokeWebContentsMethodSync('getURL') as string
try {
return new URL(urlString)
} catch (e) {
@ -111,6 +109,10 @@ class LocationProxy {
return null
}
private _invokeWebContentsMethodSync (method: string, ...args: any[]) {
return ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, method, ...args)
}
}
class BrowserWindowProxy {
@ -127,7 +129,7 @@ class BrowserWindowProxy {
}
public set location (url: string | any) {
url = resolveURL(url)
ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'loadURL', url)
this._invokeWebContentsMethodSync('loadURL', url)
}
constructor (guestId: number) {
@ -145,23 +147,35 @@ class BrowserWindowProxy {
}
public focus () {
ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus')
this._invokeWindowMethod('focus')
}
public blur () {
ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur')
this._invokeWindowMethod('blur')
}
public print () {
ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print')
this._invokeWebContentsMethod('print')
}
public postMessage (message: any, targetOrigin: any) {
ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin)
}
public eval (...args: any[]) {
ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript', ...args)
public eval (code: string) {
this._invokeWebContentsMethod('executeJavaScript', code)
}
private _invokeWindowMethod (method: string, ...args: any[]) {
return ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, method, ...args)
}
private _invokeWebContentsMethod (method: string, ...args: any[]) {
return ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
}
private _invokeWebContentsMethodSync (method: string, ...args: any[]) {
return ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, method, ...args)
}
}

View file

@ -53,4 +53,4 @@ void Initialize(v8::Handle<v8::Object> exports) {
[chromium-gin-lib]: https://code.google.com/p/chromium/codesearch#chromium/src/gin/README.md&sq=package:chromium
[electron]: http://electron.atom.io/
[electron]: https://electronjs.org/

View file

@ -1,6 +1,6 @@
{
"name": "electron",
"version": "6.0.0-nightly.20190404",
"version": "7.0.0-nightly.20190521",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
@ -47,7 +47,6 @@
"remark-preset-lint-markdown-style-guide": "^2.1.1",
"request": "^2.88.0",
"semver": "^5.6.0",
"serve": "^6.5.8",
"shx": "^0.3.2",
"standard-markdown": "^5.0.0",
"sumchecker": "^2.0.2",

View file

@ -10,7 +10,7 @@ import tempfile
from lib.config import s3_config
from lib.util import download, rm_rf, s3put, safe_mkdir
DIST_URL = 'https://atom.io/download/electron/'
DIST_URL = 'https://electronjs.org/headers/'
def main():

View file

@ -1,6 +1,5 @@
'use strict'
const assert = require('assert')
const chai = require('chai')
const ChildProcess = require('child_process')
const dirtyChai = require('dirty-chai')
@ -169,7 +168,7 @@ describe('BrowserView module', () => {
expect(view1.id).to.be.not.null()
const views = w.getBrowserViews()
expect(views.length).to.equal(2)
expect(views).to.have.lengthOf(2)
expect(views[0].webContents.id).to.equal(view1.webContents.id)
expect(views[1].webContents.id).to.equal(view2.webContents.id)
@ -243,9 +242,9 @@ describe('BrowserView module', () => {
w.setBrowserView(view)
view.webContents.once('new-window', (e, url, frameName, disposition, options, additionalFeatures) => {
e.preventDefault()
assert.strictEqual(url, 'http://host/')
assert.strictEqual(frameName, 'host')
assert.strictEqual(additionalFeatures[0], 'this-is-not-a-standard-feature')
expect(url).to.equal('http://host/')
expect(frameName).to.equal('host')
expect(additionalFeatures[0]).to.equal('this-is-not-a-standard-feature')
done()
})
view.webContents.loadFile(path.join(fixtures, 'pages', 'window-open.html'))

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const childProcess = require('child_process')
const { expect } = require('chai')
const fs = require('fs')
const http = require('http')
const multiparty = require('multiparty')
@ -12,6 +12,9 @@ const { closeWindow } = require('./window-helpers')
const { remote } = require('electron')
const { app, BrowserWindow, crashReporter } = remote
const { expect } = chai
chai.use(dirtyChai)
describe('crashReporter module', () => {
if (process.mas || process.env.DISABLE_CRASH_REPORTER_TESTS) return
@ -118,7 +121,7 @@ describe('crashReporter module', () => {
const testDone = (uploaded) => {
if (uploaded) return done(new Error('Uploaded crash report'))
if (process.platform === 'darwin') crashReporter.setUploadToServer(true)
assert(fs.existsSync(dumpFile))
expect(fs.existsSync(dumpFile)).to.be.true()
done()
}
@ -129,7 +132,7 @@ describe('crashReporter module', () => {
const dumps = files.filter((file) => /\.dmp$/.test(file) && !existingDumpFiles.has(file))
if (!dumps.length) return
assert.strictEqual(1, dumps.length)
expect(dumps).to.have.lengthOf(1)
dumpFile = path.join(crashesDir, dumps[0])
clearInterval(pollInterval)
// dump file should not be deleted when not uploading, so we wait
@ -210,21 +213,21 @@ describe('crashReporter module', () => {
it('returns the product name if one is specified', () => {
const name = crashReporter.getProductName()
const expectedName = (process.platform === 'darwin') ? 'Electron Test' : 'Zombies'
assert.strictEqual(name, expectedName)
expect(name).to.equal(expectedName)
})
})
describe('start(options)', () => {
it('requires that the companyName and submitURL options be specified', () => {
assert.throws(() => {
expect(() => {
crashReporter.start({ companyName: 'Missing submitURL' })
}, /submitURL is a required option to crashReporter\.start/)
assert.throws(() => {
}).to.throw('submitURL is a required option to crashReporter.start')
expect(() => {
crashReporter.start({ submitURL: 'Missing companyName' })
}, /companyName is a required option to crashReporter\.start/)
}).to.throw('companyName is a required option to crashReporter.start')
})
it('can be called multiple times', () => {
assert.doesNotThrow(() => {
expect(() => {
crashReporter.start({
companyName: 'Umbrella Corporation',
submitURL: 'http://127.0.0.1/crashes'
@ -234,7 +237,7 @@ describe('crashReporter module', () => {
companyName: 'Umbrella Corporation 2',
submitURL: 'http://127.0.0.1/more-crashes'
})
})
}).to.not.throw()
})
})
@ -247,14 +250,14 @@ describe('crashReporter module', () => {
} else {
dir = `${app.getPath('temp')}/Electron Test Crashes`
}
assert.strictEqual(crashesDir, dir)
expect(crashesDir).to.equal(dir)
})
})
describe('getUploadedReports', () => {
it('returns an array of reports', () => {
const reports = crashReporter.getUploadedReports()
assert(typeof reports === 'object')
expect(reports).to.be.an('array')
})
})
@ -278,7 +281,7 @@ describe('crashReporter module', () => {
? { report: cur, timestamp: timestamp }
: acc
}, { timestamp: -Infinity })
assert(newestReport, 'Hey!')
expect(newestReport).to.be.an('object')
expect(lastReport.date.getTime()).to.be.equal(
newestReport.date.getTime(),
@ -288,7 +291,7 @@ describe('crashReporter module', () => {
describe('getUploadToServer()', () => {
it('throws an error when called from the renderer process', () => {
assert.throws(() => require('electron').crashReporter.getUploadToServer())
expect(() => require('electron').crashReporter.getUploadToServer()).to.throw()
})
it('returns true when uploadToServer is set to true', function () {
if (process.platform !== 'darwin') {
@ -302,7 +305,7 @@ describe('crashReporter module', () => {
submitURL: 'http://127.0.0.1/crashes',
uploadToServer: true
})
assert.strictEqual(crashReporter.getUploadToServer(), true)
expect(crashReporter.getUploadToServer()).to.be.true()
})
it('returns false when uploadToServer is set to false', function () {
if (process.platform !== 'darwin') {
@ -317,13 +320,13 @@ describe('crashReporter module', () => {
uploadToServer: true
})
crashReporter.setUploadToServer(false)
assert.strictEqual(crashReporter.getUploadToServer(), false)
expect(crashReporter.getUploadToServer()).to.be.false()
})
})
describe('setUploadToServer(uploadToServer)', () => {
it('throws an error when called from the renderer process', () => {
assert.throws(() => require('electron').crashReporter.setUploadToServer('arg'))
expect(() => require('electron').crashReporter.setUploadToServer('arg')).to.throw()
})
it('sets uploadToServer false when called with false', function () {
if (process.platform !== 'darwin') {
@ -338,7 +341,7 @@ describe('crashReporter module', () => {
uploadToServer: true
})
crashReporter.setUploadToServer(false)
assert.strictEqual(crashReporter.getUploadToServer(), false)
expect(crashReporter.getUploadToServer()).to.be.false()
})
it('sets uploadToServer true when called with true', function () {
if (process.platform !== 'darwin') {
@ -353,7 +356,7 @@ describe('crashReporter module', () => {
uploadToServer: false
})
crashReporter.setUploadToServer(true)
assert.strictEqual(crashReporter.getUploadToServer(), true)
expect(crashReporter.getUploadToServer()).to.be.true()
})
})
@ -365,7 +368,7 @@ describe('crashReporter module', () => {
})
const parameters = crashReporter.getParameters()
assert(typeof parameters === 'object')
expect(parameters).to.be.an('object')
})
it('adds a parameter to current parameters', function () {
if (process.platform !== 'darwin') {
@ -380,7 +383,7 @@ describe('crashReporter module', () => {
})
crashReporter.addExtraParameter('hello', 'world')
assert('hello' in crashReporter.getParameters())
expect(crashReporter.getParameters()).to.have.a.property('hello')
})
it('removes a parameter from current parameters', function () {
if (process.platform !== 'darwin') {
@ -395,10 +398,10 @@ describe('crashReporter module', () => {
})
crashReporter.addExtraParameter('hello', 'world')
assert('hello' in crashReporter.getParameters())
expect(crashReporter.getParameters()).to.have.a.property('hello')
crashReporter.removeExtraParameter('hello')
assert(!('hello' in crashReporter.getParameters()))
expect(crashReporter.getParameters()).to.not.have.a.property('hello')
})
})
})
@ -428,23 +431,23 @@ const startServer = ({ callback, processType, done }) => {
if (error) throw error
if (called) return
called = true
assert.deepStrictEqual(String(fields.prod), 'Electron')
assert.strictEqual(String(fields.ver), process.versions.electron)
assert.strictEqual(String(fields.process_type), processType)
assert.strictEqual(String(fields.platform), process.platform)
assert.strictEqual(String(fields.extra1), 'extra1')
assert.strictEqual(String(fields.extra2), 'extra2')
assert.strictEqual(fields.extra3, undefined)
assert.strictEqual(String(fields._productName), 'Zombies')
assert.strictEqual(String(fields._companyName), 'Umbrella Corporation')
assert.strictEqual(String(fields._version), app.getVersion())
expect(String(fields.prod)).to.equal('Electron')
expect(String(fields.ver)).to.equal(process.versions.electron)
expect(String(fields.process_type)).to.equal(processType)
expect(String(fields.platform)).to.equal(process.platform)
expect(String(fields.extra1)).to.equal('extra1')
expect(String(fields.extra2)).to.equal('extra2')
expect(fields.extra3).to.be.undefined()
expect(String(fields._productName)).to.equal('Zombies')
expect(String(fields._companyName)).to.equal('Umbrella Corporation')
expect(String(fields._version)).to.equal(app.getVersion())
const reportId = 'abc-123-def-456-abc-789-abc-123-abcd'
res.end(reportId, () => {
waitForCrashReport().then(() => {
assert.strictEqual(crashReporter.getLastCrashReport().id, reportId)
assert.notStrictEqual(crashReporter.getUploadedReports().length, 0)
assert.strictEqual(crashReporter.getUploadedReports()[0].id, reportId)
expect(crashReporter.getLastCrashReport().id).to.equal(reportId)
expect(crashReporter.getUploadedReports()).to.be.an('array').that.is.not.empty()
expect(crashReporter.getUploadedReports()[0].id).to.equal(reportId)
req.socket.destroy()
done()
}, done)

View file

@ -2,21 +2,21 @@
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const { deprecations, deprecate } = require('electron')
const { deprecate } = require('electron')
const { expect } = chai
chai.use(dirtyChai)
describe('deprecations', () => {
describe('deprecate', () => {
beforeEach(() => {
deprecations.setHandler(null)
deprecate.setHandler(null)
process.throwDeprecation = true
})
it('allows a deprecation handler function to be specified', () => {
const messages = []
deprecations.setHandler(message => {
deprecate.setHandler(message => {
messages.push(message)
})
@ -27,17 +27,17 @@ describe('deprecations', () => {
it('returns a deprecation handler after one is set', () => {
const messages = []
deprecations.setHandler(message => {
deprecate.setHandler(message => {
messages.push(message)
})
deprecate.log('this is deprecated')
expect(deprecations.getHandler()).to.be.a('function')
expect(deprecate.getHandler()).to.be.a('function')
})
it('renames a property', () => {
let msg
deprecations.setHandler(m => { msg = m })
deprecate.setHandler(m => { msg = m })
const oldProp = 'dingyOldName'
const newProp = 'shinyNewName'
@ -68,7 +68,7 @@ describe('deprecations', () => {
it('deprecates a property of an object', () => {
let msg
deprecations.setHandler(m => { msg = m })
deprecate.setHandler(m => { msg = m })
const prop = 'itMustGo'
const o = { [prop]: 0 }
@ -84,7 +84,7 @@ describe('deprecations', () => {
it('warns exactly once when a function is deprecated with no replacement', () => {
let msg
deprecations.setHandler(m => { msg = m })
deprecate.setHandler(m => { msg = m })
function oldFn () { return 'hello' }
const deprecatedFn = deprecate.function(oldFn)
@ -96,7 +96,7 @@ describe('deprecations', () => {
it('warns exactly once when a function is deprecated with a replacement', () => {
let msg
deprecations.setHandler(m => { msg = m })
deprecate.setHandler(m => { msg = m })
function oldFn () { return 'hello' }
function newFn () { return 'goodbye' }
@ -110,7 +110,7 @@ describe('deprecations', () => {
it('warns only once per item', () => {
const messages = []
deprecations.setHandler(message => messages.push(message))
deprecate.setHandler(message => messages.push(message))
const key = 'foo'
const val = 'bar'
@ -125,7 +125,7 @@ describe('deprecations', () => {
it('warns if deprecated property is already set', () => {
let msg
deprecations.setHandler(m => { msg = m })
deprecate.setHandler(m => { msg = m })
const oldProp = 'dingyOldName'
const newProp = 'shinyNewName'
@ -146,7 +146,7 @@ describe('deprecations', () => {
it('warns when a function is deprecated in favor of a property', () => {
const warnings = []
deprecations.setHandler(warning => warnings.push(warning))
deprecate.setHandler(warning => warnings.push(warning))
const newProp = 'newProp'
const mod = {
@ -175,12 +175,12 @@ describe('deprecations', () => {
const enableCallbackWarnings = () => {
warnings = []
deprecations.setHandler(warning => warnings.push(warning))
deprecate.setHandler(warning => warnings.push(warning))
process.enablePromiseAPIs = true
}
beforeEach(() => {
deprecations.setHandler(null)
deprecate.setHandler(null)
process.throwDeprecation = true
promiseFunc = param => new Promise((resolve, reject) => resolve(param))

View file

@ -1,8 +1,29 @@
const { expect } = require('chai')
const { dialog } = require('electron').remote
const { closeWindow } = require('./window-helpers')
const { remote } = require('electron')
const { BrowserWindow, dialog } = remote
const isCI = remote.getGlobal('isCi')
describe('dialog module', () => {
describe('showOpenDialog', () => {
it('should not throw for valid cases', () => {
// Blocks the main process and can't be run in CI
if (isCI) return
let w
expect(() => {
dialog.showOpenDialog({ title: 'i am title' })
}).to.not.throw()
expect(() => {
w = new BrowserWindow()
dialog.showOpenDialog(w, { title: 'i am title' })
}).to.not.throw()
closeWindow(w).then(() => { w = null })
})
it('throws errors when the options are invalid', () => {
expect(() => {
dialog.showOpenDialog({ properties: false })
@ -27,6 +48,24 @@ describe('dialog module', () => {
})
describe('showSaveDialog', () => {
it('should not throw for valid cases', () => {
// Blocks the main process and can't be run in CI
if (isCI) return
let w
expect(() => {
dialog.showSaveDialog({ title: 'i am title' })
}).to.not.throw()
expect(() => {
w = new BrowserWindow()
dialog.showSaveDialog(w, { title: 'i am title' })
}).to.not.throw()
closeWindow(w).then(() => { w = null })
})
it('throws errors when the options are invalid', () => {
expect(() => {
dialog.showSaveDialog({ title: 300 })
@ -51,6 +90,24 @@ describe('dialog module', () => {
})
describe('showMessageBox', () => {
it('should not throw for valid cases', () => {
// Blocks the main process and can't be run in CI
if (isCI) return
let w
expect(() => {
dialog.showMessageBox({ title: 'i am title' })
}).to.not.throw()
expect(() => {
w = new BrowserWindow()
dialog.showMessageBox(w, { title: 'i am title' })
}).to.not.throw()
closeWindow(w).then(() => { w = null })
})
it('throws errors when the options are invalid', () => {
expect(() => {
dialog.showMessageBox(undefined, { type: 'not-a-valid-type' })

View file

@ -6,7 +6,7 @@ const { BrowserWindow, app, Menu, MenuItem } = remote
const roles = require('../lib/browser/api/menu-item-roles')
const { closeWindow } = require('./window-helpers')
const { expect, assert } = chai
const { expect } = chai
chai.use(dirtyChai)
describe('MenuItems', () => {
@ -492,12 +492,9 @@ describe('MenuItems', () => {
{ label: 'text', accelerator: 'Alt+A' }
])
assert.strictEqual(menu.getAcceleratorTextAt(0),
isDarwin() ? '⌘A' : 'Ctrl+A')
assert.strictEqual(menu.getAcceleratorTextAt(1),
isDarwin() ? '⇧A' : 'Shift+A')
assert.strictEqual(menu.getAcceleratorTextAt(2),
isDarwin() ? '⌥A' : 'Alt+A')
expect(menu.getAcceleratorTextAt(0)).to.equal(isDarwin() ? '⌘A' : 'Ctrl+A')
expect(menu.getAcceleratorTextAt(1)).to.equal(isDarwin() ? '⇧A' : 'Shift+A')
expect(menu.getAcceleratorTextAt(2)).to.equal(isDarwin() ? '⌥A' : 'Alt+A')
})
it('should display modifiers correctly for special keys', () => {
@ -507,12 +504,9 @@ describe('MenuItems', () => {
{ label: 'text', accelerator: 'Alt+Tab' }
])
assert.strictEqual(menu.getAcceleratorTextAt(0),
isDarwin() ? '⌘⇥\u0000' : 'Ctrl+Tab')
assert.strictEqual(menu.getAcceleratorTextAt(1),
isDarwin() ? '⇧⇥\u0000' : 'Shift+Tab')
assert.strictEqual(menu.getAcceleratorTextAt(2),
isDarwin() ? '⌥⇥\u0000' : 'Alt+Tab')
expect(menu.getAcceleratorTextAt(0)).to.equal(isDarwin() ? '⌘⇥\u0000' : 'Ctrl+Tab')
expect(menu.getAcceleratorTextAt(1)).to.equal(isDarwin() ? '⇧⇥\u0000' : 'Shift+Tab')
expect(menu.getAcceleratorTextAt(2)).to.equal(isDarwin() ? '⌥⇥\u0000' : 'Alt+Tab')
})
it('should not display modifiers twice', () => {
@ -521,10 +515,8 @@ describe('MenuItems', () => {
{ label: 'text', accelerator: 'Shift+Shift+Tab' }
])
assert.strictEqual(menu.getAcceleratorTextAt(0),
isDarwin() ? '⇧A' : 'Shift+A')
assert.strictEqual(menu.getAcceleratorTextAt(1),
isDarwin() ? '⇧⇥\u0000' : 'Shift+Tab')
expect(menu.getAcceleratorTextAt(0)).to.equal(isDarwin() ? '⇧A' : 'Shift+A')
expect(menu.getAcceleratorTextAt(1)).to.equal(isDarwin() ? '⇧⇥\u0000' : 'Shift+Tab')
})
it('should display correctly for edge cases', () => {
@ -533,10 +525,8 @@ describe('MenuItems', () => {
{ label: 'text', accelerator: 'Control+Plus' }
])
assert.strictEqual(menu.getAcceleratorTextAt(0),
isDarwin() ? '⌃⇧=' : 'Ctrl+Shift+=')
assert.strictEqual(menu.getAcceleratorTextAt(1),
isDarwin() ? '⌃⇧=' : 'Ctrl+Shift+=')
expect(menu.getAcceleratorTextAt(0)).to.equal(isDarwin() ? '⌃⇧=' : 'Ctrl+Shift+=')
expect(menu.getAcceleratorTextAt(1)).to.equal(isDarwin() ? '⌃⇧=' : 'Ctrl+Shift+=')
})
})
})

View file

@ -1,5 +1,6 @@
const assert = require('assert')
const { expect } = require('chai')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const { remote } = require('electron')
const { ipcRenderer } = require('electron')
const http = require('http')
@ -7,6 +8,9 @@ const url = require('url')
const { net } = remote
const { session } = remote
const { expect } = chai
chai.use(dirtyChai)
/* The whole net API doesn't use standard callbacks */
/* eslint-disable standard/no-callback-literal */
@ -63,7 +67,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.method, 'GET')
expect(request.method).to.equal('GET')
response.end()
break
default:
@ -72,7 +76,7 @@ describe('net module', () => {
})
const urlRequest = net.request(`${server.url}${requestUrl}`)
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -89,7 +93,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.method, 'POST')
expect(request.method).to.equal('POST')
response.end()
break
default:
@ -101,7 +105,7 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -119,7 +123,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.method, 'GET')
expect(request.method).to.equal('GET')
response.write(bodyData)
response.end()
break
@ -130,13 +134,13 @@ describe('net module', () => {
const urlRequest = net.request(`${server.url}${requestUrl}`)
urlRequest.on('response', (response) => {
let expectedBodyData = ''
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
expectedBodyData += chunk.toString()
})
response.on('end', () => {
assert.strictEqual(expectedBodyData, bodyData)
expect(expectedBodyData).to.equal(bodyData)
done()
})
response.resume()
@ -151,12 +155,12 @@ describe('net module', () => {
let postedBodyData = ''
switch (request.url) {
case requestUrl:
assert.strictEqual(request.method, 'POST')
expect(request.method).to.equal('POST')
request.on('data', (chunk) => {
postedBodyData += chunk.toString()
})
request.on('end', () => {
assert.strictEqual(postedBodyData, bodyData)
expect(postedBodyData).to.equal(bodyData)
response.end()
})
break
@ -169,7 +173,7 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {})
response.on('end', () => {
@ -189,9 +193,9 @@ describe('net module', () => {
response.statusCode = 200
response.statusMessage = 'OK'
response.chunkedEncoding = true
assert.strictEqual(request.method, 'POST')
assert.strictEqual(request.headers['transfer-encoding'], 'chunked')
assert(!request.headers['content-length'])
expect(request.method).to.equal('POST')
expect(request.headers['transfer-encoding']).to.equal('chunked')
expect(request.headers['content-length']).to.be.undefined()
request.on('data', (chunk) => {
response.write(chunk)
})
@ -213,7 +217,7 @@ describe('net module', () => {
const sentChunks = []
const receivedChunks = []
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
receivedChunks.push(chunk)
@ -221,8 +225,8 @@ describe('net module', () => {
response.on('end', () => {
const sentData = Buffer.concat(sentChunks)
const receivedData = Buffer.concat(receivedChunks)
assert.strictEqual(sentData.toString(), receivedData.toString())
assert.strictEqual(chunkIndex, chunkCount)
expect(sentData.toString()).to.equal(receivedData.toString())
expect(chunkIndex).to.be.equal(chunkCount)
done()
})
response.resume()
@ -232,7 +236,7 @@ describe('net module', () => {
chunkIndex += 1
const chunk = randomBuffer(kOneKiloByte)
sentChunks.push(chunk)
assert(urlRequest.write(chunk))
expect(urlRequest.write(chunk)).to.be.true()
}
urlRequest.end()
})
@ -270,11 +274,11 @@ describe('net module', () => {
return
}
assert(requestResponseEventEmitted)
assert(requestFinishEventEmitted)
assert(requestCloseEventEmitted)
assert(responseDataEventEmitted)
assert(responseEndEventEmitted)
expect(requestResponseEventEmitted).to.be.true()
expect(requestFinishEventEmitted).to.be.true()
expect(requestCloseEventEmitted).to.be.true()
expect(responseDataEventEmitted).to.be.true()
expect(responseEndEventEmitted).to.be.true()
done()
}
@ -285,7 +289,7 @@ describe('net module', () => {
urlRequest.on('response', (response) => {
requestResponseEventEmitted = true
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
const buffers = []
response.pause()
response.on('data', (chunk) => {
@ -294,26 +298,26 @@ describe('net module', () => {
})
response.on('end', () => {
const receivedBodyData = Buffer.concat(buffers)
assert(receivedBodyData.toString() === bodyData)
expect(receivedBodyData.toString()).to.equal(bodyData)
responseEndEventEmitted = true
maybeDone(done)
})
response.resume()
response.on('error', (error) => {
assert.ifError(error)
expect(error).to.be.an('Error')
})
response.on('aborted', () => {
assert.fail('response aborted')
expect.fail('response aborted')
})
})
urlRequest.on('finish', () => {
requestFinishEventEmitted = true
})
urlRequest.on('error', (error) => {
assert.ifError(error)
expect(error).to.be.an('Error')
})
urlRequest.on('abort', () => {
assert.fail('request aborted')
expect.fail('request aborted')
})
urlRequest.on('close', () => {
requestCloseEventEmitted = true
@ -329,8 +333,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.headers[customHeaderName.toLowerCase()],
customHeaderValue)
expect(request.headers[customHeaderName.toLowerCase()]).to.equal(customHeaderValue)
response.statusCode = 200
response.statusMessage = 'OK'
response.end()
@ -345,7 +348,7 @@ describe('net module', () => {
})
urlRequest.on('response', (response) => {
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -355,15 +358,11 @@ describe('net module', () => {
response.resume()
})
urlRequest.setHeader(customHeaderName, customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName),
customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName.toLowerCase()),
customHeaderValue)
expect(urlRequest.getHeader(customHeaderName)).to.equal(customHeaderValue)
expect(urlRequest.getHeader(customHeaderName.toLowerCase())).to.equal(customHeaderValue)
urlRequest.write('')
assert.strictEqual(urlRequest.getHeader(customHeaderName),
customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName.toLowerCase()),
customHeaderValue)
expect(urlRequest.getHeader(customHeaderName)).to.equal(customHeaderValue)
expect(urlRequest.getHeader(customHeaderName.toLowerCase())).to.equal(customHeaderValue)
urlRequest.end()
})
@ -374,14 +373,13 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.headers[customHeaderName.toLowerCase()],
customHeaderValue.toString())
expect(request.headers[customHeaderName.toLowerCase()]).to.equal(customHeaderValue.toString())
response.statusCode = 200
response.statusMessage = 'OK'
response.end()
break
default:
assert.strictEqual(request.url, requestUrl)
expect(request.url).to.equal(requestUrl)
}
})
const urlRequest = net.request({
@ -390,7 +388,7 @@ describe('net module', () => {
})
urlRequest.on('response', (response) => {
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('end', () => {
done()
@ -398,15 +396,11 @@ describe('net module', () => {
response.resume()
})
urlRequest.setHeader(customHeaderName, customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName),
customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName.toLowerCase()),
customHeaderValue)
expect(urlRequest.getHeader(customHeaderName)).to.equal(customHeaderValue)
expect(urlRequest.getHeader(customHeaderName.toLowerCase())).to.equal(customHeaderValue)
urlRequest.write('')
assert.strictEqual(urlRequest.getHeader(customHeaderName),
customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName.toLowerCase()),
customHeaderValue)
expect(urlRequest.getHeader(customHeaderName)).to.equal(customHeaderValue)
expect(urlRequest.getHeader(customHeaderName.toLowerCase())).to.equal(customHeaderValue)
urlRequest.end()
})
@ -417,7 +411,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert(!request.headers[customHeaderName.toLowerCase()])
expect(request.headers[customHeaderName.toLowerCase()]).to.be.undefined()
response.statusCode = 200
response.statusMessage = 'OK'
response.end()
@ -432,7 +426,7 @@ describe('net module', () => {
})
urlRequest.on('response', (response) => {
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -442,10 +436,10 @@ describe('net module', () => {
response.resume()
})
urlRequest.write('')
assert.throws(() => {
expect(() => {
urlRequest.setHeader(customHeaderName, customHeaderValue)
})
assert(!urlRequest.getHeader(customHeaderName))
}).to.throw()
expect(urlRequest.getHeader(customHeaderName)).to.be.undefined()
urlRequest.end()
})
@ -456,7 +450,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert(!request.headers[customHeaderName.toLowerCase()])
expect(request.headers[customHeaderName.toLowerCase()]).to.be.undefined()
response.statusCode = 200
response.statusMessage = 'OK'
response.end()
@ -471,7 +465,7 @@ describe('net module', () => {
})
urlRequest.on('response', (response) => {
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -481,10 +475,9 @@ describe('net module', () => {
response.resume()
})
urlRequest.setHeader(customHeaderName, customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName),
customHeaderValue)
expect(urlRequest.getHeader(customHeaderName)).to.equal(customHeaderValue)
urlRequest.removeHeader(customHeaderName)
assert(!urlRequest.getHeader(customHeaderName))
expect(urlRequest.getHeader(customHeaderName)).to.be.undefined()
urlRequest.write('')
urlRequest.end()
})
@ -496,8 +489,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.headers[customHeaderName.toLowerCase()],
customHeaderValue)
expect(request.headers[customHeaderName.toLowerCase()]).to.equal(customHeaderValue)
response.statusCode = 200
response.statusMessage = 'OK'
response.end()
@ -512,7 +504,7 @@ describe('net module', () => {
})
urlRequest.on('response', (response) => {
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -522,14 +514,12 @@ describe('net module', () => {
response.resume()
})
urlRequest.setHeader(customHeaderName, customHeaderValue)
assert.strictEqual(urlRequest.getHeader(customHeaderName),
customHeaderValue)
expect(urlRequest.getHeader(customHeaderName)).to.equal(customHeaderValue)
urlRequest.write('')
assert.throws(() => {
expect(() => {
urlRequest.removeHeader(customHeaderName)
})
assert.strictEqual(urlRequest.getHeader(customHeaderName),
customHeaderValue)
}).to.throw()
expect(urlRequest.getHeader(customHeaderName)).to.equal(customHeaderValue)
urlRequest.end()
})
@ -541,8 +531,7 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.headers[cookieHeaderName.toLowerCase()],
cookieHeaderValue)
expect(request.headers[cookieHeaderName.toLowerCase()]).to.equal(cookieHeaderValue)
response.statusCode = 200
response.statusMessage = 'OK'
response.end()
@ -564,7 +553,7 @@ describe('net module', () => {
})
urlRequest.on('response', (response) => {
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {})
response.on('end', () => {
@ -573,8 +562,7 @@ describe('net module', () => {
response.resume()
})
urlRequest.setHeader(cookieHeaderName, cookieHeaderValue)
assert.strictEqual(urlRequest.getHeader(cookieHeaderName),
cookieHeaderValue)
expect(urlRequest.getHeader(cookieHeaderName)).to.equal(cookieHeaderValue)
urlRequest.end()
}, (error) => {
done(error)
@ -585,7 +573,7 @@ describe('net module', () => {
const requestUrl = '/requestUrl'
server.on('request', (request, response) => {
response.end()
assert.fail('Unexpected request event')
expect.fail('Unexpected request event')
})
let requestAbortEventEmitted = false
@ -596,25 +584,25 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert.fail('Unexpected response event')
expect.fail('Unexpected response event')
})
urlRequest.on('finish', () => {
assert.fail('Unexpected finish event')
expect.fail('Unexpected finish event')
})
urlRequest.on('error', () => {
assert.fail('Unexpected error event')
expect.fail('Unexpected error event')
})
urlRequest.on('abort', () => {
requestAbortEventEmitted = true
})
urlRequest.on('close', () => {
requestCloseEventEmitted = true
assert(requestAbortEventEmitted)
assert(requestCloseEventEmitted)
expect(requestAbortEventEmitted).to.be.true()
expect(requestCloseEventEmitted).to.be.true()
done()
})
urlRequest.abort()
assert(!urlRequest.write(''))
expect(urlRequest.write('')).to.be.false()
urlRequest.end()
})
@ -640,22 +628,22 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert.fail('Unexpected response event')
expect.fail('Unexpected response event')
})
urlRequest.on('finish', () => {
assert.fail('Unexpected finish event')
expect.fail('Unexpected finish event')
})
urlRequest.on('error', () => {
assert.fail('Unexpected error event')
expect.fail('Unexpected error event')
})
urlRequest.on('abort', () => {
requestAbortEventEmitted = true
})
urlRequest.on('close', () => {
requestCloseEventEmitted = true
assert(requestReceivedByServer)
assert(requestAbortEventEmitted)
assert(requestCloseEventEmitted)
expect(requestReceivedByServer).to.be.true()
expect(requestAbortEventEmitted).to.be.true()
expect(requestCloseEventEmitted).to.be.true()
done()
})
@ -694,23 +682,23 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert.fail('Unexpected response event')
expect.fail('Unexpected response event')
})
urlRequest.on('finish', () => {
requestFinishEventEmitted = true
})
urlRequest.on('error', () => {
assert.fail('Unexpected error event')
expect.fail('Unexpected error event')
})
urlRequest.on('abort', () => {
requestAbortEventEmitted = true
})
urlRequest.on('close', () => {
requestCloseEventEmitted = true
assert(requestFinishEventEmitted)
assert(requestReceivedByServer)
assert(requestAbortEventEmitted)
assert(requestCloseEventEmitted)
expect(requestFinishEventEmitted).to.be.true()
expect(requestReceivedByServer).to.be.true()
expect(requestAbortEventEmitted).to.be.true()
expect(requestCloseEventEmitted).to.be.true()
done()
})
@ -749,16 +737,16 @@ describe('net module', () => {
urlRequest.on('response', (response) => {
requestResponseEventEmitted = true
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
response.on('end', () => {
assert.fail('Unexpected end event')
expect.fail('Unexpected end event')
})
response.resume()
response.on('error', () => {
assert.fail('Unexpected error event')
expect.fail('Unexpected error event')
})
response.on('aborted', () => {
responseAbortedEventEmitted = true
@ -769,19 +757,19 @@ describe('net module', () => {
requestFinishEventEmitted = true
})
urlRequest.on('error', () => {
assert.fail('Unexpected error event')
expect.fail('Unexpected error event')
})
urlRequest.on('abort', () => {
requestAbortEventEmitted = true
})
urlRequest.on('close', () => {
requestCloseEventEmitted = true
assert(requestFinishEventEmitted, 'request should emit "finish" event')
assert(requestReceivedByServer, 'request should be received by the server')
assert(requestResponseEventEmitted, '"response" event should be emitted')
assert(requestAbortEventEmitted, 'request should emit "abort" event')
assert(responseAbortedEventEmitted, 'response should emit "aborted" event')
assert(requestCloseEventEmitted, 'request should emit "close" event')
expect(requestFinishEventEmitted).to.be.true('request should emit "finish" event')
expect(requestReceivedByServer).to.be.true('request should be received by the server')
expect(requestResponseEventEmitted).to.be.true('"response" event should be emitted')
expect(requestAbortEventEmitted).to.be.true('request should emit "abort" event')
expect(responseAbortedEventEmitted).to.be.true('response should emit "aborted" event')
expect(requestCloseEventEmitted).to.be.true('request should emit "close" event')
done()
})
urlRequest.end(randomString(kOneKiloByte))
@ -810,13 +798,13 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', () => {
assert.fail('Unexpected response event')
expect.fail('Unexpected response event')
})
urlRequest.on('finish', () => {
requestFinishEventEmitted = true
})
urlRequest.on('error', () => {
assert.fail('Unexpected error event')
expect.fail('Unexpected error event')
})
urlRequest.on('abort', () => {
++requestAbortEventCount
@ -826,10 +814,10 @@ describe('net module', () => {
requestCloseEventEmitted = true
// Let all pending async events to be emitted
setTimeout(() => {
assert(requestFinishEventEmitted)
assert(requestReceivedByServer)
assert.strictEqual(requestAbortEventCount, 1)
assert(requestCloseEventEmitted)
expect(requestFinishEventEmitted).to.be.true()
expect(requestReceivedByServer).to.be.true()
expect(requestAbortEventCount).to.equal(1)
expect(requestCloseEventEmitted).to.be.true()
done()
}, 500)
})
@ -876,13 +864,13 @@ describe('net module', () => {
const urlRequest = net.request(`${server.url}${requestUrl}`)
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
response.on('end', () => {
assert(requestIsRedirected, 'The server should receive a request to the forward URL')
assert(requestIsIntercepted, 'The request should be intercepted by the webRequest module')
expect(requestIsRedirected).to.be.true('The server should receive a request to the forward URL')
expect(requestIsIntercepted).to.be.true('The request should be intercepted by the webRequest module')
done()
})
response.resume()
@ -907,7 +895,7 @@ describe('net module', () => {
})
session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
assert.fail('Request should not be intercepted by the default session')
expect.fail('Request should not be intercepted by the default session')
})
const customSession = session.fromPartition(customPartitionName, { cache: false })
@ -932,13 +920,13 @@ describe('net module', () => {
session: customSession
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
response.on('end', () => {
assert(requestIsRedirected, 'The server should receive a request to the forward URL')
assert(requestIsIntercepted, 'The request should be intercepted by the webRequest module')
expect(requestIsRedirected).to.be.true('The server should receive a request to the forward URL')
expect(requestIsIntercepted).to.be.true('The request should be intercepted by the webRequest module')
done()
})
response.resume()
@ -952,29 +940,29 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`,
redirect: 'custom'
}
assert.throws(() => {
expect(() => {
net.request(options)
}, 'redirect mode should be one of follow, error or manual')
}).to.throw('redirect mode should be one of follow, error or manual')
})
it('should throw when calling getHeader without a name', () => {
assert.throws(() => {
expect(() => {
net.request({ url: `${server.url}/requestUrl` }).getHeader()
}, /`name` is required for getHeader\(name\)\./)
}).to.throw(/`name` is required for getHeader\(name\)\./)
assert.throws(() => {
expect(() => {
net.request({ url: `${server.url}/requestUrl` }).getHeader(null)
}, /`name` is required for getHeader\(name\)\./)
}).to.throw(/`name` is required for getHeader\(name\)\./)
})
it('should throw when calling removeHeader without a name', () => {
assert.throws(() => {
expect(() => {
net.request({ url: `${server.url}/requestUrl` }).removeHeader()
}, /`name` is required for removeHeader\(name\)\./)
}).to.throw(/`name` is required for removeHeader\(name\)\./)
assert.throws(() => {
expect(() => {
net.request({ url: `${server.url}/requestUrl` }).removeHeader(null)
}, /`name` is required for removeHeader\(name\)\./)
}).to.throw(/`name` is required for removeHeader\(name\)\./)
})
it('should follow redirect when no redirect mode is provided', (done) => {
@ -998,7 +986,7 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
done()
})
urlRequest.end()
@ -1030,7 +1018,7 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
done()
})
urlRequest.end()
@ -1058,7 +1046,7 @@ describe('net module', () => {
redirect: 'error'
})
urlRequest.on('error', (error) => {
assert.strictEqual(error.message, 'Request cannot follow redirect with the current redirect mode')
expect(error.message).to.equal('Request cannot follow redirect with the current redirect mode')
})
urlRequest.on('close', () => {
done()
@ -1094,8 +1082,8 @@ describe('net module', () => {
redirect: 'manual'
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
assert.strictEqual(redirectCount, 2)
expect(response.statusCode).to.equal(200)
expect(redirectCount).to.equal(2)
done()
})
urlRequest.on('redirect', (status, method, url) => {
@ -1135,7 +1123,7 @@ describe('net module', () => {
redirect: 'manual'
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).that.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -1145,7 +1133,7 @@ describe('net module', () => {
response.resume()
})
urlRequest.on('close', () => {
assert.strictEqual(redirectCount, 1)
expect(redirectCount).to.equal(1)
done()
})
urlRequest.on('redirect', (status, method, url) => {
@ -1189,7 +1177,7 @@ describe('net module', () => {
})
session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
assert.fail('Request should not be intercepted by the default session')
expect.fail('Request should not be intercepted by the default session')
})
const customSession = session.fromPartition(customPartitionName, {
@ -1214,13 +1202,13 @@ describe('net module', () => {
partition: customPartitionName
})
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.equal(200)
response.pause()
response.on('data', (chunk) => {
})
response.on('end', () => {
assert(requestIsRedirected, 'The server should receive a request to the forward URL')
assert(requestIsIntercepted, 'The request should be intercepted by the webRequest module')
expect(requestIsRedirected).to.be.true('The server should receive a request to the forward URL')
expect(requestIsIntercepted).to.be.true('The request should be intercepted by the webRequest module')
done()
})
response.resume()
@ -1250,9 +1238,8 @@ describe('net module', () => {
server.on('request', (request, response) => {
switch (request.url) {
case requestUrl:
assert.strictEqual(request.method, 'GET')
assert.strictEqual(request.headers[customHeaderName.toLowerCase()],
customHeaderValue)
expect(request.method).to.equal('GET')
expect(request.headers[customHeaderName.toLowerCase()]).to.equal(customHeaderValue)
response.statusCode = 200
response.statusMessage = 'OK'
response.end()
@ -1271,7 +1258,7 @@ describe('net module', () => {
options.headers[customHeaderName] = customHeaderValue
const urlRequest = net.request(options)
urlRequest.on('response', (response) => {
assert.strictEqual(response.statusCode, 200)
expect(response.statusCode).to.be.equal(200)
response.pause()
response.on('data', (chunk) => {
})
@ -1306,7 +1293,7 @@ describe('net module', () => {
if (chunk) {
receivedBodyData += chunk.toString()
}
assert.strictEqual(receivedBodyData, bodyData)
expect(receivedBodyData).to.be.equal(bodyData)
response.end()
})
break
@ -1319,12 +1306,12 @@ describe('net module', () => {
nodeRequest.on('response', (nodeResponse) => {
const netRequest = net.request(`${server.url}${netRequestUrl}`)
netRequest.on('response', (netResponse) => {
assert.strictEqual(netResponse.statusCode, 200)
expect(netResponse.statusCode).to.be.equal(200)
netResponse.pause()
netResponse.on('data', (chunk) => {})
netResponse.on('end', () => {
assert(netRequestReceived)
assert(netRequestEnded)
expect(netRequestReceived).to.be.true()
expect(netRequestEnded).to.be.true()
done()
})
netResponse.resume()
@ -1348,11 +1335,11 @@ describe('net module', () => {
let requestErrorEventEmitted = false
const urlRequest = net.request(`${server.url}${requestUrl}`)
urlRequest.on('error', (error) => {
assert(error)
expect(error).to.be.an('Error')
requestErrorEventEmitted = true
})
urlRequest.on('close', () => {
assert(requestErrorEventEmitted)
expect(requestErrorEventEmitted).to.be.true()
done()
})
urlRequest.end()
@ -1514,7 +1501,7 @@ describe('net module', () => {
if (chunk) {
receivedBodyData += chunk.toString()
}
assert.strictEqual(receivedBodyData, bodyData)
expect(receivedBodyData).to.equal(bodyData)
response.end()
})
break
@ -1574,9 +1561,9 @@ describe('net module', () => {
url: `${server.url}${requestUrl}`
})
urlRequest.on('response', (response) => {
assert(!requestCloseEventEmitted)
expect(requestCloseEventEmitted).to.be.false()
const statusCode = response.statusCode
assert.strictEqual(statusCode, 200)
expect(statusCode).to.equal(200)
response.pause()
response.on('data', () => {
})
@ -1584,20 +1571,20 @@ describe('net module', () => {
})
response.resume()
response.on('error', () => {
assert(!requestCloseEventEmitted)
expect(requestCloseEventEmitted).to.be.false()
})
response.on('aborted', () => {
assert(!requestCloseEventEmitted)
expect(requestCloseEventEmitted).to.be.false()
})
})
urlRequest.on('finish', () => {
assert(!requestCloseEventEmitted)
expect(requestCloseEventEmitted).to.be.false()
})
urlRequest.on('error', () => {
assert(!requestCloseEventEmitted)
expect(requestCloseEventEmitted).to.be.false()
})
urlRequest.on('abort', () => {
assert(!requestCloseEventEmitted)
expect(requestCloseEventEmitted).to.be.false()
})
urlRequest.on('close', () => {
requestCloseEventEmitted = true
@ -1710,5 +1697,5 @@ describe('net module', () => {
function handleUnexpectedURL (request, response) {
response.statusCode = '500'
response.end()
assert.fail(`Unexpected URL: ${request.url}`)
expect.fail(`Unexpected URL: ${request.url}`)
}

View file

@ -1,4 +1,7 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const chaiAsPromised = require('chai-as-promised')
const http = require('http')
const path = require('path')
const qs = require('querystring')
@ -12,6 +15,10 @@ const { BrowserWindow, ipcMain, protocol, session, webContents } = remote
// and use Stream instances created in the browser process.
const stream = remote.require('stream')
const { expect } = chai
chai.use(dirtyChai)
chai.use(chaiAsPromised)
/* The whole protocol API doesn't use standard callbacks */
/* eslint-disable standard/no-callback-literal */
@ -86,9 +93,7 @@ describe('protocol module', () => {
it('throws error when scheme is already registered', async () => {
await registerStringProtocol(protocolName, emptyHandler)
assert.rejects(async () => {
await registerBufferProtocol(protocolName, emptyHandler)
})
await expect(registerBufferProtocol(protocolName, emptyHandler)).to.be.eventually.rejectedWith(Error)
})
it('does not crash when handler is called twice', async () => {
@ -102,14 +107,12 @@ describe('protocol module', () => {
}
await registerStringProtocol(protocolName, doubleHandler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('sends error when callback is called with nothing', async () => {
await registerBufferProtocol(protocolName, emptyHandler)
assert.rejects(async () => {
await ajax(protocolName + '://fake-host')
})
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(404)
})
it('does not crash when callback is called in next tick', async () => {
@ -118,15 +121,13 @@ describe('protocol module', () => {
}
await registerStringProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
})
describe('protocol.unregisterProtocol', () => {
it('returns error when scheme does not exist', async () => {
assert.rejects(async () => {
await unregisterProtocol('not-exist')
})
await expect(unregisterProtocol('not-exist')).to.be.eventually.rejectedWith(Error)
})
})
@ -135,15 +136,15 @@ describe('protocol module', () => {
const handler = (request, callback) => callback(text)
await registerStringProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('sets Access-Control-Allow-Origin', async () => {
const handler = (request, callback) => callback(text)
await registerStringProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
assert.ok(r.headers.includes('access-control-allow-origin: *'))
expect(r.data).to.equal(text)
expect(r.headers).to.include('access-control-allow-origin: *')
})
it('sends object as response', async () => {
@ -155,15 +156,13 @@ describe('protocol module', () => {
}
await registerStringProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('fails when sending object other than string', async () => {
const handler = (request, callback) => callback(new Date())
await registerStringProtocol(protocolName, handler)
assert.rejects(async () => {
await ajax(protocolName + '://fake-host')
})
expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error)
})
})
@ -173,15 +172,15 @@ describe('protocol module', () => {
const handler = (request, callback) => callback(buffer)
await registerBufferProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('sets Access-Control-Allow-Origin', async () => {
const handler = (request, callback) => callback(buffer)
await registerBufferProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
assert.ok(r.headers.includes('access-control-allow-origin: *'))
expect(r.data).to.equal(text)
expect(r.headers).to.include('access-control-allow-origin: *')
})
it('sends object as response', async () => {
@ -193,15 +192,13 @@ describe('protocol module', () => {
}
await registerBufferProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('fails when sending string', async () => {
const handler = (request, callback) => callback(text)
await registerBufferProtocol(protocolName, handler)
assert.rejects(async () => {
await ajax(protocolName + '://fake-host')
})
expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error)
})
})
@ -215,15 +212,15 @@ describe('protocol module', () => {
const handler = (request, callback) => callback(filePath)
await registerFileProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, String(fileContent))
expect(r.data).to.equal(String(fileContent))
})
it('sets Access-Control-Allow-Origin', async () => {
const handler = (request, callback) => callback(filePath)
await registerFileProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, String(fileContent))
assert.ok(r.headers.includes('access-control-allow-origin: *'))
expect(r.data).to.equal(String(fileContent))
expect(r.headers).to.include('access-control-allow-origin: *')
})
it('sets custom headers', async () => {
@ -233,46 +230,42 @@ describe('protocol module', () => {
})
await registerFileProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, String(fileContent))
assert.ok(r.headers.includes('x-great-header: sogreat'))
expect(r.data).to.equal(String(fileContent))
expect(r.headers).to.include('x-great-header: sogreat')
})
it('sends object as response', async () => {
const handler = (request, callback) => callback({ path: filePath })
await registerFileProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, String(fileContent))
expect(r.data).to.equal(String(fileContent))
})
it('can send normal file', async () => {
const handler = (request, callback) => callback(normalPath)
await registerFileProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, String(normalContent))
expect(r.data).to.equal(String(normalContent))
})
it('fails when sending unexist-file', async () => {
const fakeFilePath = path.join(fixtures, 'asar', 'a.asar', 'not-exist')
const handler = (request, callback) => callback(fakeFilePath)
await registerFileProtocol(protocolName, handler)
assert.rejects(async () => {
await ajax(protocolName + '://fake-host')
})
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(404)
})
it('fails when sending unsupported content', async () => {
const handler = (request, callback) => callback(new Date())
await registerFileProtocol(protocolName, handler)
assert.rejects(async () => {
await ajax(protocolName + '://fake-host')
})
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(404)
})
})
describe('protocol.registerHttpProtocol', () => {
it('sends url as response', async () => {
const server = http.createServer((req, res) => {
assert.notStrictEqual(req.headers.accept, '')
expect(req.headers.accept).to.not.equal('')
res.end(text)
server.close()
})
@ -283,23 +276,19 @@ describe('protocol module', () => {
const handler = (request, callback) => callback({ url })
await registerHttpProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('fails when sending invalid url', async () => {
const handler = (request, callback) => callback({ url: 'url' })
await registerHttpProtocol(protocolName, handler)
assert.rejects(async () => {
await ajax(protocolName + '://fake-host')
})
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(404)
})
it('fails when sending unsupported content', async () => {
const handler = (request, callback) => callback(new Date())
await registerHttpProtocol(protocolName, handler)
assert.rejects(async () => {
await ajax(protocolName + '://fake-host')
})
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(404)
})
it('works when target URL redirects', async () => {
@ -322,12 +311,12 @@ describe('protocol module', () => {
await registerHttpProtocol(protocolName, handler)
await contents.loadURL(url)
assert.strictEqual(contents.getURL(), url)
expect(contents.getURL()).to.equal(url)
})
it('can access request headers', (done) => {
const handler = (request) => {
assert.ok('headers' in request)
expect(request).to.have.a.property('headers')
done()
}
registerHttpProtocol(protocolName, handler, () => {
@ -341,15 +330,15 @@ describe('protocol module', () => {
const handler = (request, callback) => callback(getStream())
await registerStreamProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('sends object as response', async () => {
const handler = (request, callback) => callback({ data: getStream() })
await registerStreamProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
assert.strictEqual(r.status, 200)
expect(r.data).to.equal(text)
expect(r.status).to.equal(200)
})
it('sends custom response headers', async () => {
@ -361,9 +350,9 @@ describe('protocol module', () => {
})
await registerStreamProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, text)
assert.strictEqual(r.status, 200)
assert.ok(r.headers.includes('x-electron: a, b'))
expect(r.data).to.equal(text)
expect(r.status).to.equal(200)
expect(r.headers).to.include('x-electron: a, b')
})
it('sends custom status code', async () => {
@ -373,8 +362,8 @@ describe('protocol module', () => {
})
await registerStreamProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data, undefined)
assert.strictEqual(r.status, 204)
expect(r.data).to.be.undefined()
expect(r.status).to.equal(204)
})
it('receives request headers', async () => {
@ -388,7 +377,7 @@ describe('protocol module', () => {
}
await registerStreamProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host', { headers: { 'x-return-headers': 'yes' } })
assert.strictEqual(r.data['x-return-headers'], 'yes')
expect(r.data['x-return-headers']).to.equal('yes')
})
it('returns response multiple response headers with the same name', async () => {
@ -406,7 +395,7 @@ describe('protocol module', () => {
// SUBTLE: when the response headers have multiple values it
// separates values by ", ". When the response headers are incorrectly
// converting an array to a string it separates values by ",".
assert.strictEqual(r.headers, 'header1: value1, value2\r\nheader2: value3\r\n')
expect(r.headers).to.equal('header1: value1, value2\r\nheader2: value3\r\n')
})
it('can handle large responses', async () => {
@ -416,48 +405,48 @@ describe('protocol module', () => {
}
await registerStreamProtocol(protocolName, handler)
const r = await ajax(protocolName + '://fake-host')
assert.strictEqual(r.data.length, data.length)
expect(r.data).to.have.lengthOf(data.length)
})
})
describe('protocol.isProtocolHandled', () => {
it('returns true for about:', async () => {
const result = await protocol.isProtocolHandled('about')
assert.strictEqual(result, true)
expect(result).to.be.true()
})
it('returns true for file:', async () => {
const result = await protocol.isProtocolHandled('file')
assert.strictEqual(result, true)
expect(result).to.be.true()
})
it('returns true for http:', async () => {
const result = await protocol.isProtocolHandled('http')
assert.strictEqual(result, true)
expect(result).to.be.true()
})
it('returns true for https:', async () => {
const result = await protocol.isProtocolHandled('https')
assert.strictEqual(result, true)
expect(result).to.be.true()
})
it('returns false when scheme is not registered', async () => {
const result = await protocol.isProtocolHandled('no-exist')
assert.strictEqual(result, false)
expect(result).to.be.false()
})
it('returns true for custom protocol', async () => {
const emptyHandler = (request, callback) => callback()
await registerStringProtocol(protocolName, emptyHandler)
const result = await protocol.isProtocolHandled(protocolName)
assert.strictEqual(result, true)
expect(result).to.be.true()
})
it('returns true for intercepted protocol', async () => {
const emptyHandler = (request, callback) => callback()
await interceptStringProtocol('http', emptyHandler)
const result = await protocol.isProtocolHandled('http')
assert.strictEqual(result, true)
expect(result).to.be.true()
})
})
@ -465,9 +454,9 @@ describe('protocol module', () => {
const emptyHandler = (request, callback) => callback()
it('throws error when scheme is already intercepted', (done) => {
protocol.interceptStringProtocol('http', emptyHandler, (error) => {
assert.strictEqual(error, null)
expect(error).to.be.null()
protocol.interceptBufferProtocol('http', emptyHandler, (error) => {
assert.notStrictEqual(error, null)
expect(error).to.not.be.null()
done()
})
})
@ -484,14 +473,12 @@ describe('protocol module', () => {
}
await interceptStringProtocol('http', doubleHandler)
const r = await ajax('http://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.be.equal(text)
})
it('sends error when callback is called with nothing', async () => {
await interceptStringProtocol('http', emptyHandler)
assert.rejects(async () => {
await ajax('http://fake-host')
})
await expect(ajax('http://fake-host')).to.be.eventually.rejectedWith(404)
})
})
@ -500,7 +487,7 @@ describe('protocol module', () => {
const handler = (request, callback) => callback(text)
await interceptStringProtocol('http', handler)
const r = await ajax('http://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('can set content-type', async () => {
@ -512,8 +499,8 @@ describe('protocol module', () => {
}
await interceptStringProtocol('http', handler)
const r = await ajax('http://fake-host')
assert.strictEqual(typeof r.data, 'object')
assert.strictEqual(r.data.value, 1)
expect(r.data).to.be.an('object')
expect(r.data).to.have.a.property('value').that.is.equal(1)
})
it('can receive post data', async () => {
@ -523,7 +510,7 @@ describe('protocol module', () => {
}
await interceptStringProtocol('http', handler)
const r = await ajax('http://fake-host', { type: 'POST', data: postData })
assert.deepStrictEqual({ ...qs.parse(r.data) }, postData)
expect({ ...qs.parse(r.data) }).to.deep.equal(postData)
})
})
@ -532,7 +519,7 @@ describe('protocol module', () => {
const handler = (request, callback) => callback(Buffer.from(text))
await interceptBufferProtocol('http', handler)
const r = await ajax('http://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('can receive post data', async () => {
@ -542,7 +529,7 @@ describe('protocol module', () => {
}
await interceptBufferProtocol('http', handler)
const r = await ajax('http://fake-host', { type: 'POST', data: postData })
assert.strictEqual(r.data, $.param(postData))
expect(r.data).to.equal($.param(postData))
})
})
@ -580,13 +567,13 @@ describe('protocol module', () => {
}
await interceptHttpProtocol('http', handler)
const r = await ajax('http://fake-host', { type: 'POST', data: postData })
assert.deepStrictEqual({ ...qs.parse(r.data) }, postData)
expect({ ...qs.parse(r.data) }).to.deep.equal(postData)
})
it('can use custom session', async () => {
const customSession = session.fromPartition('custom-ses', { cache: false })
customSession.webRequest.onBeforeRequest((details, callback) => {
assert.strictEqual(details.url, 'http://fake-host/')
expect(details.url).to.equal('http://fake-host/')
callback({ cancel: true })
})
after(() => customSession.webRequest.onBeforeRequest(null))
@ -598,14 +585,12 @@ describe('protocol module', () => {
})
}
await interceptHttpProtocol('http', handler)
assert.rejects(async () => {
await fetch('http://fake-host')
})
await expect(fetch('http://fake-host')).to.be.eventually.rejectedWith(Error)
})
it('can access request headers', (done) => {
const handler = (request) => {
assert.ok('headers' in request)
expect(request).to.have.a.property('headers')
done()
}
protocol.interceptHttpProtocol('http', handler, () => {
@ -619,7 +604,7 @@ describe('protocol module', () => {
const handler = (request, callback) => callback(getStream())
await interceptStreamProtocol('http', handler)
const r = await ajax('http://fake-host')
assert.strictEqual(r.data, text)
expect(r.data).to.equal(text)
})
it('can receive post data', async () => {
@ -628,7 +613,7 @@ describe('protocol module', () => {
}
await interceptStreamProtocol('http', handler)
const r = await ajax('http://fake-host', { type: 'POST', data: postData })
assert.deepStrictEqual({ ...qs.parse(r.data) }, postData)
expect({ ...qs.parse(r.data) }).to.deep.equal(postData)
})
it('can execute redirects', async () => {
@ -644,27 +629,23 @@ describe('protocol module', () => {
})
}, 300)
} else {
assert.strictEqual(request.url.indexOf('http://fake-redirect'), 0)
expect(request.url.indexOf('http://fake-redirect')).to.equal(0)
callback(getStream(1, 'redirect'))
}
}
await interceptStreamProtocol('http', handler)
const r = await ajax('http://fake-host')
assert.strictEqual(r.data, 'redirect')
expect(r.data).to.equal('redirect')
})
})
describe('protocol.uninterceptProtocol', () => {
it('returns error when scheme does not exist', async () => {
assert.rejects(async () => {
await protocol.uninterceptProtocol('not-exist')
})
await expect(uninterceptProtocol('not-exist')).to.be.eventually.rejectedWith(Error)
})
it('returns error when scheme is not intercepted', async () => {
assert.rejects(async () => {
await protocol.uninterceptProtocol('http')
})
await expect(uninterceptProtocol('http')).to.be.eventually.rejectedWith(Error)
})
})
@ -773,7 +754,7 @@ describe('protocol module', () => {
it('supports fetch api by default', async () => {
const url = 'file://' + fixtures + '/assets/logo.png'
const response = await window.fetch(url)
assert(response.ok)
expect(response.ok).to.be.true()
})
it('allows CORS requests by default', async () => {
@ -836,8 +817,8 @@ describe('protocol module', () => {
const event = emittedOnce(ipcMain, 'response')
newContents.loadURL(standardScheme + '://fake-host')
const args = await event
assert.strictEqual(args[1], expected)
const [, response] = await event
expect(response).to.equal(expected)
}
})
})

View file

@ -1,11 +1,10 @@
'use strict'
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const path = require('path')
const { closeWindow } = require('./window-helpers')
const { resolveGetters } = require('./assert-helpers')
const { resolveGetters } = require('./expect-helpers')
const { remote, ipcRenderer } = require('electron')
const { ipcMain, BrowserWindow } = remote
@ -18,7 +17,7 @@ const comparePaths = (path1, path2) => {
path1 = path1.toLowerCase()
path2 = path2.toLowerCase()
}
assert.strictEqual(path1, path2)
expect(path1).to.equal(path2)
}
describe('remote module', () => {
@ -68,23 +67,23 @@ describe('remote module', () => {
it('should returns same object for the same module', () => {
const dialog1 = remote.require('electron')
const dialog2 = remote.require('electron')
assert.strictEqual(dialog1, dialog2)
expect(dialog1).to.equal(dialog2)
})
it('should work when object contains id property', () => {
const a = remote.require(path.join(fixtures, 'module', 'id.js'))
assert.strictEqual(a.id, 1127)
expect(a.id).to.equal(1127)
})
it('should work when object has no prototype', () => {
const a = remote.require(path.join(fixtures, 'module', 'no-prototype.js'))
assert.strictEqual(a.foo.constructor.name, '')
assert.strictEqual(a.foo.bar, 'baz')
assert.strictEqual(a.foo.baz, false)
assert.strictEqual(a.bar, 1234)
assert.strictEqual(a.anonymous.constructor.name, '')
assert.strictEqual(a.getConstructorName(Object.create(null)), '')
assert.strictEqual(a.getConstructorName(new (class {})()), '')
expect(a.foo.constructor.name).to.equal('')
expect(a.foo.bar).to.equal('baz')
expect(a.foo.baz).to.equal(false)
expect(a.bar).to.equal(1234)
expect(a.anonymous.constructor.name).to.equal('')
expect(a.getConstructorName(Object.create(null))).to.equal('')
expect(a.getConstructorName(new (class {})())).to.equal('')
})
it('should search module from the user app', () => {
@ -94,41 +93,41 @@ describe('remote module', () => {
it('should work with function properties', () => {
let a = remote.require(path.join(fixtures, 'module', 'export-function-with-properties.js'))
assert.strictEqual(typeof a, 'function')
assert.strictEqual(a.bar, 'baz')
expect(a).to.be.a('function')
expect(a.bar).to.equal('baz')
a = remote.require(path.join(fixtures, 'module', 'function-with-properties.js'))
assert.strictEqual(typeof a, 'object')
assert.strictEqual(a.foo(), 'hello')
assert.strictEqual(a.foo.bar, 'baz')
assert.strictEqual(a.foo.nested.prop, 'yes')
assert.strictEqual(a.foo.method1(), 'world')
assert.strictEqual(a.foo.method1.prop1(), 123)
expect(a).to.be.an('object')
expect(a.foo()).to.equal('hello')
expect(a.foo.bar).to.equal('baz')
expect(a.foo.nested.prop).to.equal('yes')
expect(a.foo.method1()).to.equal('world')
expect(a.foo.method1.prop1()).to.equal(123)
assert.ok(Object.keys(a.foo).includes('bar'))
assert.ok(Object.keys(a.foo).includes('nested'))
assert.ok(Object.keys(a.foo).includes('method1'))
expect(a.foo).to.have.a.property('bar')
expect(a.foo).to.have.a.property('nested')
expect(a.foo).to.have.a.property('method1')
a = remote.require(path.join(fixtures, 'module', 'function-with-missing-properties.js')).setup()
assert.strictEqual(a.bar(), true)
assert.strictEqual(a.bar.baz, undefined)
expect(a.bar()).to.equal(true)
expect(a.bar.baz).to.be.undefined()
})
it('should work with static class members', () => {
const a = remote.require(path.join(fixtures, 'module', 'remote-static.js'))
assert.strictEqual(typeof a.Foo, 'function')
assert.strictEqual(a.Foo.foo(), 3)
assert.strictEqual(a.Foo.bar, 'baz')
expect(a.Foo).to.be.a('function')
expect(a.Foo.foo()).to.equal(3)
expect(a.Foo.bar).to.equal('baz')
const foo = new a.Foo()
assert.strictEqual(foo.baz(), 123)
expect(foo.baz()).to.equal(123)
})
it('includes the length of functions specified as arguments', () => {
const a = remote.require(path.join(fixtures, 'module', 'function-with-args.js'))
assert.strictEqual(a((a, b, c, d, f) => {}), 5)
assert.strictEqual(a((a) => {}), 1)
assert.strictEqual(a((...args) => {}), 0)
expect(a((a, b, c, d, f) => {})).to.equal(5)
expect(a((a) => {})).to.equal(1)
expect(a((...args) => {})).to.equal(0)
})
it('handles circular references in arrays and objects', () => {
@ -137,7 +136,7 @@ describe('remote module', () => {
let arrayA = ['foo']
const arrayB = [arrayA, 'bar']
arrayA.push(arrayB)
assert.deepStrictEqual(a.returnArgs(arrayA, arrayB), [
expect(a.returnArgs(arrayA, arrayB)).to.deep.equal([
['foo', [null, 'bar']],
[['foo', null], 'bar']
])
@ -145,40 +144,40 @@ describe('remote module', () => {
let objectA = { foo: 'bar' }
const objectB = { baz: objectA }
objectA.objectB = objectB
assert.deepStrictEqual(a.returnArgs(objectA, objectB), [
expect(a.returnArgs(objectA, objectB)).to.deep.equal([
{ foo: 'bar', objectB: { baz: null } },
{ baz: { foo: 'bar', objectB: null } }
])
arrayA = [1, 2, 3]
assert.deepStrictEqual(a.returnArgs({ foo: arrayA }, { bar: arrayA }), [
expect(a.returnArgs({ foo: arrayA }, { bar: arrayA })).to.deep.equal([
{ foo: [1, 2, 3] },
{ bar: [1, 2, 3] }
])
objectA = { foo: 'bar' }
assert.deepStrictEqual(a.returnArgs({ foo: objectA }, { bar: objectA }), [
expect(a.returnArgs({ foo: objectA }, { bar: objectA })).to.deep.equal([
{ foo: { foo: 'bar' } },
{ bar: { foo: 'bar' } }
])
arrayA = []
arrayA.push(arrayA)
assert.deepStrictEqual(a.returnArgs(arrayA), [
expect(a.returnArgs(arrayA)).to.deep.equal([
[null]
])
objectA = {}
objectA.foo = objectA
objectA.bar = 'baz'
assert.deepStrictEqual(a.returnArgs(objectA), [
expect(a.returnArgs(objectA)).to.deep.equal([
{ foo: null, bar: 'baz' }
])
objectA = {}
objectA.foo = { bar: objectA }
objectA.bar = 'baz'
assert.deepStrictEqual(a.returnArgs(objectA), [
expect(a.returnArgs(objectA)).to.deep.equal([
{ foo: { bar: null }, bar: 'baz' }
])
})
@ -189,83 +188,83 @@ describe('remote module', () => {
const buf = Buffer.from('test')
const call = remote.require(path.join(fixtures, 'module', 'call.js'))
const result = call.call(remote.createFunctionWithReturnValue(buf))
assert.strictEqual(result.constructor.name, 'Buffer')
expect(result).to.be.an.instanceOf(Buffer)
})
})
describe('remote modules', () => {
it('includes browser process modules as properties', () => {
assert.strictEqual(typeof remote.app.getPath, 'function')
assert.strictEqual(typeof remote.webContents.getFocusedWebContents, 'function')
assert.strictEqual(typeof remote.clipboard.readText, 'function')
expect(remote.app.getPath).to.be.a('function')
expect(remote.webContents.getFocusedWebContents).to.be.a('function')
expect(remote.clipboard.readText).to.be.a('function')
})
it('returns toString() of original function via toString()', () => {
const { readText } = remote.clipboard
assert(readText.toString().startsWith('function'))
expect(readText.toString().startsWith('function')).to.be.true()
const { functionWithToStringProperty } = remote.require(path.join(fixtures, 'module', 'to-string-non-function.js'))
assert.strictEqual(functionWithToStringProperty.toString, 'hello')
expect(functionWithToStringProperty.toString).to.equal('hello')
})
})
describe('remote object in renderer', () => {
it('can change its properties', () => {
const property = remote.require(path.join(fixtures, 'module', 'property.js'))
assert.strictEqual(property.property, 1127)
expect(property).to.have.a.property('property').that.is.equal(1127)
property.property = null
assert.strictEqual(property.property, null)
expect(property).to.have.a.property('property').that.is.null()
property.property = undefined
assert.strictEqual(property.property, undefined)
expect(property).to.have.a.property('property').that.is.undefined()
property.property = 1007
assert.strictEqual(property.property, 1007)
expect(property).to.have.a.property('property').that.is.equal(1007)
assert.strictEqual(property.getFunctionProperty(), 'foo-browser')
expect(property.getFunctionProperty()).to.equal('foo-browser')
property.func.property = 'bar'
assert.strictEqual(property.getFunctionProperty(), 'bar-browser')
expect(property.getFunctionProperty()).to.equal('bar-browser')
property.func.property = 'foo' // revert back
const property2 = remote.require(path.join(fixtures, 'module', 'property.js'))
assert.strictEqual(property2.property, 1007)
expect(property2.property).to.equal(1007)
property.property = 1127
})
it('rethrows errors getting/setting properties', () => {
const foo = remote.require(path.join(fixtures, 'module', 'error-properties.js'))
assert.throws(() => {
expect(() => {
// eslint-disable-next-line
foo.bar
}, /getting error/)
}).to.throw('getting error')
assert.throws(() => {
expect(() => {
foo.bar = 'test'
}, /setting error/)
}).to.throw('setting error')
})
it('can set a remote property with a remote object', () => {
const foo = remote.require(path.join(fixtures, 'module', 'remote-object-set.js'))
assert.doesNotThrow(() => {
expect(() => {
foo.bar = remote.getCurrentWindow()
})
}).to.not.throw()
})
it('can construct an object from its member', () => {
const call = remote.require(path.join(fixtures, 'module', 'call.js'))
const obj = new call.constructor()
assert.strictEqual(obj.test, 'test')
expect(obj.test).to.equal('test')
})
it('can reassign and delete its member functions', () => {
const remoteFunctions = remote.require(path.join(fixtures, 'module', 'function.js'))
assert.strictEqual(remoteFunctions.aFunction(), 1127)
expect(remoteFunctions.aFunction()).to.equal(1127)
remoteFunctions.aFunction = () => { return 1234 }
assert.strictEqual(remoteFunctions.aFunction(), 1234)
expect(remoteFunctions.aFunction()).to.equal(1234)
assert.strictEqual(delete remoteFunctions.aFunction, true)
expect(delete remoteFunctions.aFunction).to.equal(true)
})
it('is referenced by its members', () => {
@ -280,35 +279,35 @@ describe('remote module', () => {
const printName = remote.require(print)
it('converts NaN to undefined', () => {
assert.strictEqual(printName.getNaN(), undefined)
assert.strictEqual(printName.echo(NaN), undefined)
expect(printName.getNaN()).to.be.undefined()
expect(printName.echo(NaN)).to.be.undefined()
})
it('converts Infinity to undefined', () => {
assert.strictEqual(printName.getInfinity(), undefined)
assert.strictEqual(printName.echo(Infinity), undefined)
expect(printName.getInfinity()).to.be.undefined()
expect(printName.echo(Infinity)).to.be.undefined()
})
it('keeps its constructor name for objects', () => {
const buf = Buffer.from('test')
assert.strictEqual(printName.print(buf), 'Buffer')
expect(printName.print(buf)).to.equal('Buffer')
})
it('supports instanceof Date', () => {
const now = new Date()
assert.strictEqual(printName.print(now), 'Date')
assert.deepStrictEqual(printName.echo(now), now)
expect(printName.print(now)).to.equal('Date')
expect(printName.echo(now)).to.deep.equal(now)
})
it('supports instanceof Buffer', () => {
const buffer = Buffer.from('test')
assert.ok(buffer.equals(printName.echo(buffer)))
expect(buffer.equals(printName.echo(buffer))).to.be.true()
const objectWithBuffer = { a: 'foo', b: Buffer.from('bar') }
assert.ok(objectWithBuffer.b.equals(printName.echo(objectWithBuffer).b))
expect(objectWithBuffer.b.equals(printName.echo(objectWithBuffer).b)).to.be.true()
const arrayWithBuffer = [1, 2, Buffer.from('baz')]
assert.ok(arrayWithBuffer[2].equals(printName.echo(arrayWithBuffer)[2]))
expect(arrayWithBuffer[2].equals(printName.echo(arrayWithBuffer)[2])).to.be.true()
})
it('supports instanceof ArrayBuffer', () => {
@ -316,89 +315,89 @@ describe('remote module', () => {
const view = new DataView(buffer)
view.setFloat64(0, Math.PI)
assert.deepStrictEqual(printName.echo(buffer), buffer)
assert.strictEqual(printName.print(buffer), 'ArrayBuffer')
expect(printName.echo(buffer)).to.deep.equal(buffer)
expect(printName.print(buffer)).to.equal('ArrayBuffer')
})
it('supports instanceof Int8Array', () => {
const values = [1, 2, 3, 4]
assert.deepStrictEqual([...printName.typedArray('Int8Array', values)], values)
expect([...printName.typedArray('Int8Array', values)]).to.deep.equal(values)
const int8values = new Int8Array(values)
assert.deepStrictEqual(printName.typedArray('Int8Array', int8values), int8values)
assert.strictEqual(printName.print(int8values), 'Int8Array')
expect(printName.typedArray('Int8Array', int8values)).to.deep.equal(int8values)
expect(printName.print(int8values)).to.equal('Int8Array')
})
it('supports instanceof Uint8Array', () => {
const values = [1, 2, 3, 4]
assert.deepStrictEqual([...printName.typedArray('Uint8Array', values)], values)
expect([...printName.typedArray('Uint8Array', values)]).to.deep.equal(values)
const uint8values = new Uint8Array(values)
assert.deepStrictEqual(printName.typedArray('Uint8Array', uint8values), uint8values)
assert.strictEqual(printName.print(uint8values), 'Uint8Array')
expect(printName.typedArray('Uint8Array', uint8values)).to.deep.equal(uint8values)
expect(printName.print(uint8values)).to.equal('Uint8Array')
})
it('supports instanceof Uint8ClampedArray', () => {
const values = [1, 2, 3, 4]
assert.deepStrictEqual([...printName.typedArray('Uint8ClampedArray', values)], values)
expect([...printName.typedArray('Uint8ClampedArray', values)]).to.deep.equal(values)
const uint8values = new Uint8ClampedArray(values)
assert.deepStrictEqual(printName.typedArray('Uint8ClampedArray', uint8values), uint8values)
assert.strictEqual(printName.print(uint8values), 'Uint8ClampedArray')
expect(printName.typedArray('Uint8ClampedArray', uint8values)).to.deep.equal(uint8values)
expect(printName.print(uint8values)).to.equal('Uint8ClampedArray')
})
it('supports instanceof Int16Array', () => {
const values = [0x1234, 0x2345, 0x3456, 0x4567]
assert.deepStrictEqual([...printName.typedArray('Int16Array', values)], values)
expect([...printName.typedArray('Int16Array', values)]).to.deep.equal(values)
const int16values = new Int16Array(values)
assert.deepStrictEqual(printName.typedArray('Int16Array', int16values), int16values)
assert.strictEqual(printName.print(int16values), 'Int16Array')
expect(printName.typedArray('Int16Array', int16values)).to.deep.equal(int16values)
expect(printName.print(int16values)).to.equal('Int16Array')
})
it('supports instanceof Uint16Array', () => {
const values = [0x1234, 0x2345, 0x3456, 0x4567]
assert.deepStrictEqual([...printName.typedArray('Uint16Array', values)], values)
expect([...printName.typedArray('Uint16Array', values)]).to.deep.equal(values)
const uint16values = new Uint16Array(values)
assert.deepStrictEqual(printName.typedArray('Uint16Array', uint16values), uint16values)
assert.strictEqual(printName.print(uint16values), 'Uint16Array')
expect(printName.typedArray('Uint16Array', uint16values)).to.deep.equal(uint16values)
expect(printName.print(uint16values)).to.equal('Uint16Array')
})
it('supports instanceof Int32Array', () => {
const values = [0x12345678, 0x23456789]
assert.deepStrictEqual([...printName.typedArray('Int32Array', values)], values)
expect([...printName.typedArray('Int32Array', values)]).to.deep.equal(values)
const int32values = new Int32Array(values)
assert.deepStrictEqual(printName.typedArray('Int32Array', int32values), int32values)
assert.strictEqual(printName.print(int32values), 'Int32Array')
expect(printName.typedArray('Int32Array', int32values)).to.deep.equal(int32values)
expect(printName.print(int32values)).to.equal('Int32Array')
})
it('supports instanceof Uint32Array', () => {
const values = [0x12345678, 0x23456789]
assert.deepStrictEqual([...printName.typedArray('Uint32Array', values)], values)
expect([...printName.typedArray('Uint32Array', values)]).to.deep.equal(values)
const uint32values = new Uint32Array(values)
assert.deepStrictEqual(printName.typedArray('Uint32Array', uint32values), uint32values)
assert.strictEqual(printName.print(uint32values), 'Uint32Array')
expect(printName.typedArray('Uint32Array', uint32values)).to.deep.equal(uint32values)
expect(printName.print(uint32values)).to.equal('Uint32Array')
})
it('supports instanceof Float32Array', () => {
const values = [0.5, 1.0, 1.5]
assert.deepStrictEqual([...printName.typedArray('Float32Array', values)], values)
expect([...printName.typedArray('Float32Array', values)]).to.deep.equal(values)
const float32values = new Float32Array()
assert.deepStrictEqual(printName.typedArray('Float32Array', float32values), float32values)
assert.strictEqual(printName.print(float32values), 'Float32Array')
expect(printName.typedArray('Float32Array', float32values)).to.deep.equal(float32values)
expect(printName.print(float32values)).to.equal('Float32Array')
})
it('supports instanceof Float64Array', () => {
const values = [0.5, 1.0, 1.5]
assert.deepStrictEqual([...printName.typedArray('Float64Array', values)], values)
expect([...printName.typedArray('Float64Array', values)]).to.deep.equal(values)
const float64values = new Float64Array([0.5, 1.0, 1.5])
assert.deepStrictEqual(printName.typedArray('Float64Array', float64values), float64values)
assert.strictEqual(printName.print(float64values), 'Float64Array')
expect(printName.typedArray('Float64Array', float64values)).to.deep.equal(float64values)
expect(printName.print(float64values)).to.equal('Float64Array')
})
})
@ -406,7 +405,7 @@ describe('remote module', () => {
it('can be used as promise in each side', (done) => {
const promise = remote.require(path.join(fixtures, 'module', 'promise.js'))
promise.twicePromise(Promise.resolve(1234)).then((value) => {
assert.strictEqual(value, 2468)
expect(value).to.equal(2468)
done()
})
})
@ -414,7 +413,7 @@ describe('remote module', () => {
it('handles rejections via catch(onRejected)', (done) => {
const promise = remote.require(path.join(fixtures, 'module', 'rejected-promise.js'))
promise.reject(Promise.resolve(1234)).catch((error) => {
assert.strictEqual(error.message, 'rejected')
expect(error.message).to.equal('rejected')
done()
})
})
@ -422,7 +421,7 @@ describe('remote module', () => {
it('handles rejections via then(onFulfilled, onRejected)', (done) => {
const promise = remote.require(path.join(fixtures, 'module', 'rejected-promise.js'))
promise.reject(Promise.resolve(1234)).then(() => {}, (error) => {
assert.strictEqual(error.message, 'rejected')
expect(error.message).to.equal('rejected')
done()
})
})
@ -436,7 +435,7 @@ describe('remote module', () => {
promise.reject().then(() => {
done(new Error('Promise was not rejected'))
}).catch((error) => {
assert.strictEqual(error.message, 'rejected')
expect(error.message).to.equal('rejected')
done()
})
})
@ -444,7 +443,7 @@ describe('remote module', () => {
it('emits unhandled rejection events in the renderer process', (done) => {
window.addEventListener('unhandledrejection', function handler (event) {
event.preventDefault()
assert.strictEqual(event.reason.message, 'rejected')
expect(event.reason.message).to.equal('rejected')
window.removeEventListener('unhandledrejection', handler)
done()
})
@ -460,7 +459,7 @@ describe('remote module', () => {
it('can return same object with different getters', () => {
const contents1 = remote.getCurrentWindow().webContents
const contents2 = remote.getCurrentWebContents()
assert(contents1 === contents2)
expect(contents1).to.equal(contents2)
})
})
@ -494,39 +493,39 @@ describe('remote module', () => {
let derived = cl.derived
it('can get methods', () => {
assert.strictEqual(base.method(), 'method')
expect(base.method()).to.equal('method')
})
it('can get properties', () => {
assert.strictEqual(base.readonly, 'readonly')
expect(base.readonly).to.equal('readonly')
})
it('can change properties', () => {
assert.strictEqual(base.value, 'old')
expect(base.value).to.equal('old')
base.value = 'new'
assert.strictEqual(base.value, 'new')
expect(base.value).to.equal('new')
base.value = 'old'
})
it('has unenumerable methods', () => {
assert(!base.hasOwnProperty('method'))
assert(Object.getPrototypeOf(base).hasOwnProperty('method'))
expect(base).to.not.have.own.property('method')
expect(Object.getPrototypeOf(base)).to.have.own.property('method')
})
it('keeps prototype chain in derived class', () => {
assert.strictEqual(derived.method(), 'method')
assert.strictEqual(derived.readonly, 'readonly')
assert(!derived.hasOwnProperty('method'))
expect(derived.method()).to.equal('method')
expect(derived.readonly).to.equal('readonly')
expect(derived).to.not.have.own.property('method')
const proto = Object.getPrototypeOf(derived)
assert(!proto.hasOwnProperty('method'))
assert(Object.getPrototypeOf(proto).hasOwnProperty('method'))
expect(proto).to.not.have.own.property('method')
expect(Object.getPrototypeOf(proto)).to.have.own.property('method')
})
it('is referenced by methods in prototype chain', () => {
const method = derived.method
derived = null
global.gc()
assert.strictEqual(method(), 'method')
expect(method()).to.equal('method')
})
})
@ -534,9 +533,9 @@ describe('remote module', () => {
const throwFunction = remote.require(path.join(fixtures, 'module', 'exception.js'))
it('throws errors from the main process', () => {
assert.throws(() => {
expect(() => {
throwFunction()
})
}).to.throw()
})
it('throws custom errors from the main process', () => {
@ -546,8 +545,8 @@ describe('remote module', () => {
try {
throwFunction(err)
} catch (error) {
assert.ok(error.from)
assert.deepStrictEqual(error.cause, ...resolveGetters(err))
expect(error.from).to.equal('browser')
expect(error.cause).to.deep.equal(...resolveGetters(err))
}
})
})

View file

@ -1,4 +1,3 @@
const assert = require('assert')
const chai = require('chai')
const http = require('http')
const https = require('https')
@ -46,13 +45,13 @@ describe('session module', () => {
describe('session.defaultSession', () => {
it('returns the default session', () => {
assert.strictEqual(session.defaultSession, session.fromPartition(''))
expect(session.defaultSession).to.equal(session.fromPartition(''))
})
})
describe('session.fromPartition(partition, options)', () => {
it('returns existing session with same partition', () => {
assert.strictEqual(session.fromPartition('test'), session.fromPartition('test'))
expect(session.fromPartition('test')).to.equal(session.fromPartition('test'))
})
it('created session is ref-counted', () => {
@ -60,10 +59,10 @@ describe('session module', () => {
const userAgent = 'test-agent'
const ses1 = session.fromPartition(partition)
ses1.setUserAgent(userAgent)
assert.strictEqual(ses1.getUserAgent(), userAgent)
expect(ses1.getUserAgent()).to.equal(userAgent)
ses1.destroy()
const ses2 = session.fromPartition(partition)
assert.notStrictEqual(ses2.getUserAgent(), userAgent)
expect(ses2.getUserAgent()).to.not.equal(userAgent)
})
})
@ -119,7 +118,7 @@ describe('session module', () => {
await cookies.set({ url, name, value, expirationDate: (+new Date()) / 1000 + 120 })
const list = await cookies.get({ url })
assert(list.some(cookie => cookie.name === name && cookie.value === value))
expect(list.some(cookie => cookie.name === name && cookie.value === value)).to.be.true()
}
})
@ -132,7 +131,7 @@ describe('session module', () => {
await cookies.remove(url, name)
const list = await cookies.get({ url })
assert(!list.some(cookie => cookie.name === name && cookie.value === value))
expect(list.some(cookie => cookie.name === name && cookie.value === value)).to.be.false()
})
it('should set cookie for standard scheme', async () => {
@ -202,7 +201,7 @@ describe('session module', () => {
appProcess.stdout.on('data', data => { output += data })
appProcess.stdout.on('end', () => {
output = output.replace(/(\r\n|\n|\r)/gm, '')
assert.strictEqual(output, result)
expect(output).to.equal(result)
resolve()
})
})
@ -218,7 +217,7 @@ describe('session module', () => {
it('clears localstorage data', (done) => {
ipcMain.on('count', (event, count) => {
ipcMain.removeAllListeners('count')
assert.strictEqual(count, 0)
expect(count).to.equal(0)
done()
})
w.webContents.on('did-finish-load', () => {
@ -265,9 +264,9 @@ describe('session module', () => {
ipcRenderer.sendSync('set-download-option', false, true)
w.loadURL(url)
ipcRenderer.once('download-error', (event, downloadUrl, filename, error) => {
assert.strictEqual(downloadUrl, url)
assert.strictEqual(filename, 'mockFile.txt')
assert.strictEqual(error, 'Object has been destroyed')
expect(downloadUrl).to.equal(url)
expect(filename).to.equal('mockFile.txt')
expect(error).to.equal('Object has been destroyed')
done()
})
})
@ -296,20 +295,20 @@ describe('session module', () => {
const assertDownload = (event, state, url, mimeType,
receivedBytes, totalBytes, disposition,
filename, port, savePath, isCustom) => {
assert.strictEqual(state, 'completed')
assert.strictEqual(filename, 'mock.pdf')
assert.ok(path.isAbsolute(savePath))
assert.ok(isPathEqual(savePath, path.join(__dirname, 'fixtures', 'mock.pdf')))
expect(state).to.equal('completed')
expect(filename).to.equal('mock.pdf')
expect(path.isAbsolute(savePath)).to.be.true()
expect(isPathEqual(savePath, path.join(__dirname, 'fixtures', 'mock.pdf'))).to.be.true()
if (isCustom) {
assert.strictEqual(url, `${protocolName}://item`)
expect(url).to.be.equal(`${protocolName}://item`)
} else {
assert.strictEqual(url, `http://127.0.0.1:${port}/`)
expect(url).to.be.equal(`http://127.0.0.1:${port}/`)
}
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, mockPDF.length)
assert.strictEqual(totalBytes, mockPDF.length)
assert.strictEqual(disposition, contentDisposition)
assert(fs.existsSync(downloadFilePath))
expect(mimeType).to.equal('application/pdf')
expect(receivedBytes).to.equal(mockPDF.length)
expect(totalBytes).to.equal(mockPDF.length)
expect(disposition).to.equal(contentDisposition)
expect(fs.existsSync(downloadFilePath)).to.be.true()
fs.unlinkSync(downloadFilePath)
}
@ -384,12 +383,12 @@ describe('session module', () => {
mimeType, receivedBytes,
totalBytes, disposition,
filename) => {
assert.strictEqual(state, 'cancelled')
assert.strictEqual(filename, 'mock.pdf')
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, 0)
assert.strictEqual(totalBytes, mockPDF.length)
assert.strictEqual(disposition, contentDisposition)
expect(state).to.equal('cancelled')
expect(filename).to.equal('mock.pdf')
expect(mimeType).to.equal('application/pdf')
expect(receivedBytes).to.equal(0)
expect(totalBytes).to.equal(mockPDF.length)
expect(disposition).to.equal(contentDisposition)
done()
})
})
@ -410,12 +409,12 @@ describe('session module', () => {
mimeType, receivedBytes,
totalBytes, disposition,
filename) => {
assert.strictEqual(state, 'cancelled')
assert.strictEqual(filename, 'download.pdf')
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, 0)
assert.strictEqual(totalBytes, mockPDF.length)
assert.strictEqual(disposition, contentDisposition)
expect(state).to.equal('cancelled')
expect(filename).to.equal('download.pdf')
expect(mimeType).to.equal('application/pdf')
expect(receivedBytes).to.equal(0)
expect(totalBytes).to.equal(mockPDF.length)
expect(disposition).to.equal(contentDisposition)
done()
})
})
@ -457,7 +456,7 @@ describe('session module', () => {
it('does not display a save dialog and reports the done state as interrupted', (done) => {
ipcRenderer.sendSync('set-download-option', false, false)
ipcRenderer.once('download-done', (event, state) => {
assert.strictEqual(state, 'interrupted')
expect(state).to.equal('interrupted')
done()
})
w.webContents.downloadURL(`file://${path.join(__dirname, 'does-not-exist.txt')}`)
@ -495,10 +494,10 @@ describe('session module', () => {
it('does not affect defaultSession', async () => {
const result1 = await protocol.isProtocolHandled(protocolName)
assert.strictEqual(result1, false)
expect(result1).to.equal(false)
const result2 = await customSession.protocol.isProtocolHandled(protocolName)
assert.strictEqual(result2, true)
expect(result2).to.equal(true)
})
it('handles requests from partition', (done) => {
@ -533,7 +532,7 @@ describe('session module', () => {
const config = { proxyRules: 'http=myproxy:80' }
await customSession.setProxy(config)
const proxy = await customSession.resolveProxy('http://example.com/')
assert.strictEqual(proxy, 'PROXY myproxy:80')
expect(proxy).to.equal('PROXY myproxy:80')
})
it('allows removing the implicit bypass rules for localhost', async () => {
@ -544,7 +543,7 @@ describe('session module', () => {
await customSession.setProxy(config)
const proxy = await customSession.resolveProxy('http://localhost')
assert.strictEqual(proxy, 'PROXY myproxy:80')
expect(proxy).to.equal('PROXY myproxy:80')
})
it('allows configuring proxy settings with pacScript', async () => {
@ -565,7 +564,7 @@ describe('session module', () => {
const config = { pacScript: `http://127.0.0.1:${server.address().port}` }
await customSession.setProxy(config)
const proxy = await customSession.resolveProxy('https://google.com')
assert.strictEqual(proxy, 'PROXY myproxy:8132')
expect(proxy).to.equal('PROXY myproxy:8132')
resolve()
} catch (error) {
reject(error)
@ -581,7 +580,7 @@ describe('session module', () => {
}
await customSession.setProxy(config)
const proxy = await customSession.resolveProxy('http://example/')
assert.strictEqual(proxy, 'DIRECT')
expect(proxy).to.equal('DIRECT')
})
})
@ -621,9 +620,9 @@ describe('session module', () => {
callback({ data: content, mimeType: 'text/html' })
} else if (request.method === 'POST') {
const uuid = request.uploadData[1].blobUUID
assert(uuid)
expect(uuid).to.be.a('string')
session.defaultSession.getBlobData(uuid).then(result => {
assert.strictEqual(result.toString(), postData)
expect(result.toString()).to.equal(postData)
done()
})
}
@ -664,13 +663,13 @@ describe('session module', () => {
it('accepts the request when the callback is called with 0', (done) => {
session.defaultSession.setCertificateVerifyProc(({ hostname, certificate, verificationResult, errorCode }, callback) => {
assert(['net::ERR_CERT_AUTHORITY_INVALID', 'net::ERR_CERT_COMMON_NAME_INVALID'].includes(verificationResult), verificationResult)
assert([-202, -200].includes(errorCode), errorCode)
expect(['net::ERR_CERT_AUTHORITY_INVALID', 'net::ERR_CERT_COMMON_NAME_INVALID'].includes(verificationResult)).to.be.true()
expect([-202, -200].includes(errorCode)).to.be.true()
callback(0)
})
w.webContents.once('did-finish-load', () => {
assert.strictEqual(w.webContents.getTitle(), 'hello')
expect(w.webContents.getTitle()).to.equal('hello')
done()
})
w.loadURL(`https://127.0.0.1:${server.address().port}`)
@ -678,23 +677,23 @@ describe('session module', () => {
it('rejects the request when the callback is called with -2', (done) => {
session.defaultSession.setCertificateVerifyProc(({ hostname, certificate, verificationResult }, callback) => {
assert.strictEqual(hostname, '127.0.0.1')
assert.strictEqual(certificate.issuerName, 'Intermediate CA')
assert.strictEqual(certificate.subjectName, 'localhost')
assert.strictEqual(certificate.issuer.commonName, 'Intermediate CA')
assert.strictEqual(certificate.subject.commonName, 'localhost')
assert.strictEqual(certificate.issuerCert.issuer.commonName, 'Root CA')
assert.strictEqual(certificate.issuerCert.subject.commonName, 'Intermediate CA')
assert.strictEqual(certificate.issuerCert.issuerCert.issuer.commonName, 'Root CA')
assert.strictEqual(certificate.issuerCert.issuerCert.subject.commonName, 'Root CA')
assert.strictEqual(certificate.issuerCert.issuerCert.issuerCert, undefined)
assert(['net::ERR_CERT_AUTHORITY_INVALID', 'net::ERR_CERT_COMMON_NAME_INVALID'].includes(verificationResult), verificationResult)
expect(hostname).to.equal('127.0.0.1')
expect(certificate.issuerName).to.equal('Intermediate CA')
expect(certificate.subjectName).to.equal('localhost')
expect(certificate.issuer.commonName).to.equal('Intermediate CA')
expect(certificate.subject.commonName).to.equal('localhost')
expect(certificate.issuerCert.issuer.commonName).to.equal('Root CA')
expect(certificate.issuerCert.subject.commonName).to.equal('Intermediate CA')
expect(certificate.issuerCert.issuerCert.issuer.commonName).to.equal('Root CA')
expect(certificate.issuerCert.issuerCert.subject.commonName).to.equal('Root CA')
expect(certificate.issuerCert.issuerCert.issuerCert).to.be.undefined()
expect(['net::ERR_CERT_AUTHORITY_INVALID', 'net::ERR_CERT_COMMON_NAME_INVALID'].includes(verificationResult)).to.be.true()
callback(-2)
})
const url = `https://127.0.0.1:${server.address().port}`
w.webContents.once('did-finish-load', () => {
assert.strictEqual(w.webContents.getTitle(), url)
expect(w.webContents.getTitle()).to.equal(url)
done()
})
w.loadURL(url)
@ -717,12 +716,12 @@ describe('session module', () => {
mimeType, receivedBytes,
totalBytes, filename,
savePath) => {
assert.strictEqual(state, 'interrupted')
assert.deepStrictEqual(urlChain, ['http://127.0.0.1/'])
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, 0)
assert.strictEqual(totalBytes, 5242880)
assert.strictEqual(savePath, filePath)
expect(state).to.equal('interrupted')
expect(urlChain).to.deep.equal(['http://127.0.0.1/'])
expect(mimeType).to.equal('application/pdf')
expect(receivedBytes).to.equal(0)
expect(totalBytes).to.equal(5242880)
expect(savePath).to.equal(filePath)
done()
})
})
@ -756,14 +755,14 @@ describe('session module', () => {
ipcRenderer.sendSync('set-download-option', false, false, downloadFilePath)
w.webContents.session.createInterruptedDownload(options)
} else {
assert.strictEqual(state, 'completed')
assert.strictEqual(filename, 'logo.png')
assert.strictEqual(savePath, downloadFilePath)
assert.strictEqual(url, downloadUrl)
assert.strictEqual(mimeType, 'image/png')
assert.strictEqual(receivedBytes, 14022)
assert.strictEqual(totalBytes, 14022)
assert(fs.existsSync(downloadFilePath))
expect(state).to.equal('completed')
expect(filename).to.equal('logo.png')
expect(savePath).to.equal(downloadFilePath)
expect(url).to.equal(downloadUrl)
expect(mimeType).to.equal('image/png')
expect(receivedBytes).to.equal(14022)
expect(totalBytes).to.equal(14022)
expect(fs.existsSync(downloadFilePath)).to.be.true()
fs.unlinkSync(downloadFilePath)
rangeServer.close()
ipcRenderer.removeListener('download-done', callback)
@ -802,8 +801,8 @@ describe('session module', () => {
})
request.on('login', (info, callback) => {
attempt += 1
assert.strictEqual(info.scheme, 'basic')
assert.strictEqual(info.realm, 'Restricted')
expect(info.scheme).to.equal('basic')
expect(info.realm).to.equal('Restricted')
callback('test', 'test')
})
request.on('response', (response) => {
@ -813,7 +812,7 @@ describe('session module', () => {
data += chunk
})
response.on('end', () => {
assert.strictEqual(data, 'authenticated')
expect(data).to.equal('authenticated')
ses.clearAuthCache({ type: 'password' }).then(() => {
issueLoginRequest(attempt)
})
@ -839,8 +838,8 @@ describe('session module', () => {
webview = new WebView()
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'message')
assert.deepStrictEqual(e.args, ['SecurityError'])
expect(e.channel).to.equal('message')
expect(e.args).to.deep.equal(['SecurityError'])
done()
})
webview.src = `file://${fixtures}/pages/permissions/midi-sysex.html`

View file

@ -1,9 +1,14 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const fs = require('fs')
const path = require('path')
const os = require('os')
const { shell } = require('electron')
const { expect } = chai
chai.use(dirtyChai)
describe('shell module', () => {
const fixtures = path.resolve(__dirname, 'fixtures')
const shortcutOptions = {
@ -54,14 +59,14 @@ describe('shell module', () => {
})
it('throws when failed', () => {
assert.throws(() => {
expect(() => {
shell.readShortcutLink('not-exist')
}, /Failed to read shortcut link/)
}).to.throw('Failed to read shortcut link')
})
it('reads all properties of a shortcut', () => {
const shortcut = shell.readShortcutLink(path.join(fixtures, 'assets', 'shortcut.lnk'))
assert.deepStrictEqual(shortcut, shortcutOptions)
expect(shortcut).to.deep.equal(shortcutOptions)
})
})
@ -77,28 +82,28 @@ describe('shell module', () => {
})
it('writes the shortcut', () => {
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, { target: 'C:\\' }), true)
assert.strictEqual(fs.existsSync(tmpShortcut), true)
expect(shell.writeShortcutLink(tmpShortcut, { target: 'C:\\' })).to.be.true()
expect(fs.existsSync(tmpShortcut)).to.be.true()
})
it('correctly sets the fields', () => {
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, shortcutOptions), true)
assert.deepStrictEqual(shell.readShortcutLink(tmpShortcut), shortcutOptions)
expect(shell.writeShortcutLink(tmpShortcut, shortcutOptions)).to.be.true()
expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions)
})
it('updates the shortcut', () => {
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, 'update', shortcutOptions), false)
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions), true)
assert.deepStrictEqual(shell.readShortcutLink(tmpShortcut), shortcutOptions)
expect(shell.writeShortcutLink(tmpShortcut, 'update', shortcutOptions)).to.be.false()
expect(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions)).to.be.true()
expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions)
const change = { target: 'D:\\' }
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, 'update', change), true)
assert.deepStrictEqual(shell.readShortcutLink(tmpShortcut), Object.assign(shortcutOptions, change))
expect(shell.writeShortcutLink(tmpShortcut, 'update', change)).to.be.true()
expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(Object.assign(shortcutOptions, change))
})
it('replaces the shortcut', () => {
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, 'replace', shortcutOptions), false)
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions), true)
assert.deepStrictEqual(shell.readShortcutLink(tmpShortcut), shortcutOptions)
expect(shell.writeShortcutLink(tmpShortcut, 'replace', shortcutOptions)).to.be.false()
expect(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions)).to.be.true()
expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions)
const change = {
target: 'D:\\',
description: 'description2',
@ -108,8 +113,8 @@ describe('shell module', () => {
icon: 'icon2',
iconIndex: 2
}
assert.strictEqual(shell.writeShortcutLink(tmpShortcut, 'replace', change), true)
assert.deepStrictEqual(shell.readShortcutLink(tmpShortcut), change)
expect(shell.writeShortcutLink(tmpShortcut, 'replace', change)).to.be.true()
expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(change)
})
})
})

View file

@ -1,7 +1,12 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const { remote } = require('electron')
const { systemPreferences } = remote
const { expect } = chai
chai.use(dirtyChai)
describe('systemPreferences module', () => {
describe('systemPreferences.getAccentColor', () => {
before(function () {
@ -12,8 +17,7 @@ describe('systemPreferences module', () => {
it('should return a non-empty string', () => {
const accentColor = systemPreferences.getAccentColor()
assert.notStrictEqual(accentColor, null)
assert(accentColor.length > 0)
expect(accentColor).to.be.a('string').that.is.not.empty()
})
})
@ -25,13 +29,13 @@ describe('systemPreferences module', () => {
})
it('throws an error when the id is invalid', () => {
assert.throws(() => {
expect(() => {
systemPreferences.getColor('not-a-color')
}, /Unknown color: not-a-color/)
}).to.throw('Unknown color: not-a-color')
})
it('returns a hex RGB color string', () => {
assert.strictEqual(/^#[0-9A-F]{6}$/i.test(systemPreferences.getColor('window')), true)
expect(systemPreferences.getColor('window')).to.match(/^#[0-9A-F]{6}$/i)
})
})
@ -57,7 +61,7 @@ describe('systemPreferences module', () => {
for (const userDefault of defaultsMap) {
const { key, value: expectedValue, type } = userDefault
const actualValue = systemPreferences.getUserDefault(key, type)
assert.deepStrictEqual(actualValue, expectedValue)
expect(actualValue).to.deep.equal(expectedValue)
}
})
@ -70,9 +74,9 @@ describe('systemPreferences module', () => {
]
for (const badDefault of badDefaults) {
assert.throws(() => {
expect(() => {
systemPreferences.registerDefaults(badDefault)
}, 'Invalid userDefault data provided')
}).to.throw('Invalid userDefault data provided')
}
})
})
@ -86,24 +90,22 @@ describe('systemPreferences module', () => {
it('returns values for known user defaults', () => {
const locale = systemPreferences.getUserDefault('AppleLocale', 'string')
assert.strictEqual(typeof locale, 'string')
assert(locale.length > 0)
expect(locale).to.be.a('string').that.is.not.empty()
const languages = systemPreferences.getUserDefault('AppleLanguages', 'array')
assert(Array.isArray(languages))
assert(languages.length > 0)
expect(languages).to.be.an('array').that.is.not.empty()
})
it('returns values for unknown user defaults', () => {
assert.strictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'boolean'), false)
assert.strictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'integer'), 0)
assert.strictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'float'), 0)
assert.strictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'double'), 0)
assert.strictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'string'), '')
assert.strictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'url'), '')
assert.strictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'badtype'), undefined)
assert.deepStrictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'array'), [])
assert.deepStrictEqual(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'dictionary'), {})
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'boolean')).to.equal(false)
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'integer')).to.equal(0)
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'float')).to.equal(0)
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'double')).to.equal(0)
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'string')).to.equal('')
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'url')).to.equal('')
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'badtype')).to.be.undefined()
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'array')).to.deep.equal([])
expect(systemPreferences.getUserDefault('UserDefaultDoesNotExist', 'dictionary')).to.deep.equal({})
})
})
@ -130,22 +132,22 @@ describe('systemPreferences module', () => {
for (const [type, value] of TEST_CASES) {
systemPreferences.setUserDefault(KEY, type, value)
const retrievedValue = systemPreferences.getUserDefault(KEY, type)
assert.deepStrictEqual(retrievedValue, value)
expect(retrievedValue).to.deep.equal(value)
}
})
it('throws when type and value conflict', () => {
for (const [type, value] of TEST_CASES) {
assert.throws(() => {
expect(() => {
systemPreferences.setUserDefault(KEY, type, typeof value === 'string' ? {} : 'foo')
}, `Unable to convert value to: ${type}`)
}).to.throw(`Unable to convert value to: ${type}`)
}
})
it('throws when type is not valid', () => {
assert.throws(() => {
expect(() => {
systemPreferences.setUserDefault(KEY, 'abc', 'foo')
}, 'Invalid type: abc')
}).to.throw('Invalid type: abc')
})
})
@ -160,7 +162,7 @@ describe('systemPreferences module', () => {
const KEY = 'SystemPreferencesTest'
systemPreferences.setUserDefault(KEY, 'string', 'foo')
systemPreferences.removeUserDefault(KEY)
assert.strictEqual(systemPreferences.getUserDefault(KEY, 'string'), '')
expect(systemPreferences.getUserDefault(KEY, 'string')).to.equal('')
})
it('does not throw for missing keys', () => {
@ -170,17 +172,17 @@ describe('systemPreferences module', () => {
describe('systemPreferences.isInvertedColorScheme()', () => {
it('returns a boolean', () => {
assert.strictEqual(typeof systemPreferences.isInvertedColorScheme(), 'boolean')
expect(systemPreferences.isInvertedColorScheme()).to.be.a('boolean')
})
})
describe('systemPreferences.getAnimationSettings()', () => {
it('returns an object with all properties', () => {
const settings = systemPreferences.getAnimationSettings()
assert.strictEqual(typeof settings, 'object')
assert.strictEqual(typeof settings.shouldRenderRichAnimation, 'boolean')
assert.strictEqual(typeof settings.scrollAnimationsEnabledBySystem, 'boolean')
assert.strictEqual(typeof settings.prefersReducedMotion, 'boolean')
expect(settings).to.be.an('object')
expect(settings).to.have.a.property('shouldRenderRichAnimation').that.is.a('boolean')
expect(settings).to.have.a.property('scrollAnimationsEnabledBySystem').that.is.a('boolean')
expect(settings).to.have.a.property('prefersReducedMotion').that.is.a('boolean')
})
})
})

View file

@ -1,36 +1,36 @@
const assert = require('assert')
const path = require('path')
const { BrowserWindow, TouchBar } = require('electron').remote
const { closeWindow } = require('./window-helpers')
const { expect } = require('chai')
const { TouchBarButton, TouchBarColorPicker, TouchBarGroup } = TouchBar
const { TouchBarLabel, TouchBarPopover, TouchBarScrubber, TouchBarSegmentedControl, TouchBarSlider, TouchBarSpacer } = TouchBar
describe('TouchBar module', () => {
it('throws an error when created without an options object', () => {
assert.throws(() => {
expect(() => {
const touchBar = new TouchBar()
touchBar.toString()
}, /Must specify options object as first argument/)
}).to.throw('Must specify options object as first argument')
})
it('throws an error when created with invalid items', () => {
assert.throws(() => {
expect(() => {
const touchBar = new TouchBar({ items: [1, true, {}, []] })
touchBar.toString()
}, /Each item must be an instance of TouchBarItem/)
}).to.throw('Each item must be an instance of TouchBarItem')
})
it('throws an error when an invalid escape item is set', () => {
assert.throws(() => {
expect(() => {
const touchBar = new TouchBar({ items: [], escapeItem: 'esc' })
touchBar.toString()
}, /Escape item must be an instance of TouchBarItem/)
}).to.throw('Escape item must be an instance of TouchBarItem')
assert.throws(() => {
expect(() => {
const touchBar = new TouchBar({ items: [] })
touchBar.escapeItem = 'esc'
}, /Escape item must be an instance of TouchBarItem/)
}).to.throw('Escape item must be an instance of TouchBarItem')
})
describe('BrowserWindow behavior', () => {

View file

@ -1,6 +1,5 @@
'use strict'
const assert = require('assert')
const ChildProcess = require('child_process')
const fs = require('fs')
const os = require('os')
@ -146,15 +145,15 @@ describe('webContents module', () => {
if (isCi) return done()
const specWebContents = remote.getCurrentWebContents()
assert.strictEqual(specWebContents.id, webContents.getFocusedWebContents().id)
expect(specWebContents.id).to.equal(webContents.getFocusedWebContents().id)
specWebContents.once('devtools-opened', () => {
assert.strictEqual(specWebContents.devToolsWebContents.id, webContents.getFocusedWebContents().id)
expect(specWebContents.devToolsWebContents.id).to.equal(webContents.getFocusedWebContents().id)
specWebContents.closeDevTools()
})
specWebContents.once('devtools-closed', () => {
assert.strictEqual(specWebContents.id, webContents.getFocusedWebContents().id)
expect(specWebContents.id).to.equal(webContents.getFocusedWebContents().id)
done()
})
@ -165,16 +164,16 @@ describe('webContents module', () => {
const specWebContents = w.webContents
specWebContents.once('devtools-opened', () => {
assert.doesNotThrow(() => {
expect(() => {
webContents.getFocusedWebContents()
})
}).to.not.throw()
specWebContents.closeDevTools()
})
specWebContents.once('devtools-closed', () => {
assert.doesNotThrow(() => {
expect(() => {
webContents.getFocusedWebContents()
})
}).to.not.throw()
done()
})
@ -200,7 +199,7 @@ describe('webContents module', () => {
describe('isFocused() API', () => {
it('returns false when the window is hidden', () => {
BrowserWindow.getAllWindows().forEach((window) => {
assert.strictEqual(!window.isVisible() && window.webContents.isFocused(), false)
expect(!window.isVisible() && window.webContents.isFocused()).to.be.false()
})
})
})
@ -217,8 +216,7 @@ describe('webContents module', () => {
oscillator.start()
let p = emittedOnce(webContents, '-audio-state-changed')
await context.resume()
const [, audible] = await p
assert(webContents.isCurrentlyAudible() === audible)
await p
expect(webContents.isCurrentlyAudible()).to.be.true()
p = emittedOnce(webContents, '-audio-state-changed')
oscillator.stop()
@ -233,7 +231,7 @@ describe('webContents module', () => {
it('should not crash when called for devTools webContents', (done) => {
w.webContents.openDevTools()
w.webContents.once('devtools-opened', () => {
assert(!w.devToolsWebContents.getWebPreferences())
expect(w.devToolsWebContents.getWebPreferences()).to.be.null()
done()
})
})
@ -244,18 +242,18 @@ describe('webContents module', () => {
const focused = emittedOnce(w, 'focus')
w.show()
await focused
assert.strictEqual(w.isFocused(), true)
expect(w.isFocused()).to.be.true()
const devtoolsOpened = emittedOnce(w.webContents, 'devtools-opened')
w.webContents.openDevTools({ mode: 'detach', activate: true })
await devtoolsOpened
assert.strictEqual(w.isFocused(), false)
expect(w.isFocused()).to.be.false()
})
it('can show window without activation', async () => {
const devtoolsOpened = emittedOnce(w.webContents, 'devtools-opened')
w.webContents.openDevTools({ mode: 'detach', activate: false })
await devtoolsOpened
assert.strictEqual(w.isDevToolsOpened(), true)
expect(w.isDevToolsOpened()).to.be.true()
})
})
@ -268,7 +266,7 @@ describe('webContents module', () => {
ipcRenderer.sendSync('prevent-next-input-event', 'a', w.webContents.id)
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'a' })
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'b' })
assert.strictEqual(await keyDown, 'b')
expect(await keyDown).to.equal('b')
})
it('has the correct properties', async () => {
@ -289,14 +287,14 @@ describe('webContents module', () => {
})
const [, input] = await p
assert.strictEqual(input.type, opts.type)
assert.strictEqual(input.key, opts.key)
assert.strictEqual(input.code, opts.code)
assert.strictEqual(input.isAutoRepeat, opts.isAutoRepeat)
assert.strictEqual(input.shift, opts.shift)
assert.strictEqual(input.control, opts.control)
assert.strictEqual(input.alt, opts.alt)
assert.strictEqual(input.meta, opts.meta)
expect(input.type).to.equal(opts.type)
expect(input.key).to.equal(opts.key)
expect(input.code).to.equal(opts.code)
expect(input.isAutoRepeat).to.equal(opts.isAutoRepeat)
expect(input.shift).to.equal(opts.shift)
expect(input.control).to.equal(opts.control)
expect(input.alt).to.equal(opts.alt)
expect(input.meta).to.equal(opts.meta)
}
await testBeforeInput({
type: 'keyDown',
@ -449,12 +447,12 @@ describe('webContents module', () => {
it('can send keydown events', (done) => {
ipcMain.once('keydown', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
assert.strictEqual(key, 'a')
assert.strictEqual(code, 'KeyA')
assert.strictEqual(keyCode, 65)
assert.strictEqual(shiftKey, false)
assert.strictEqual(ctrlKey, false)
assert.strictEqual(altKey, false)
expect(key).to.equal('a')
expect(code).to.equal('KeyA')
expect(keyCode).to.equal(65)
expect(shiftKey).to.be.false()
expect(ctrlKey).to.be.false()
expect(altKey).to.be.false()
done()
})
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' })
@ -462,12 +460,12 @@ describe('webContents module', () => {
it('can send keydown events with modifiers', (done) => {
ipcMain.once('keydown', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
assert.strictEqual(key, 'Z')
assert.strictEqual(code, 'KeyZ')
assert.strictEqual(keyCode, 90)
assert.strictEqual(shiftKey, true)
assert.strictEqual(ctrlKey, true)
assert.strictEqual(altKey, false)
expect(key).to.equal('Z')
expect(code).to.equal('KeyZ')
expect(keyCode).to.equal(90)
expect(shiftKey).to.be.true()
expect(ctrlKey).to.be.true()
expect(altKey).to.be.false()
done()
})
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl'] })
@ -475,12 +473,12 @@ describe('webContents module', () => {
it('can send keydown events with special keys', (done) => {
ipcMain.once('keydown', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
assert.strictEqual(key, 'Tab')
assert.strictEqual(code, 'Tab')
assert.strictEqual(keyCode, 9)
assert.strictEqual(shiftKey, false)
assert.strictEqual(ctrlKey, false)
assert.strictEqual(altKey, true)
expect(key).to.equal('Tab')
expect(code).to.equal('Tab')
expect(keyCode).to.equal(9)
expect(shiftKey).to.be.false()
expect(ctrlKey).to.be.false()
expect(altKey).to.be.true()
done()
})
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Tab', modifiers: ['alt'] })
@ -488,12 +486,12 @@ describe('webContents module', () => {
it('can send char events', (done) => {
ipcMain.once('keypress', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
assert.strictEqual(key, 'a')
assert.strictEqual(code, 'KeyA')
assert.strictEqual(keyCode, 65)
assert.strictEqual(shiftKey, false)
assert.strictEqual(ctrlKey, false)
assert.strictEqual(altKey, false)
expect(key).to.equal('a')
expect(code).to.equal('KeyA')
expect(keyCode).to.equal(65)
expect(shiftKey).to.be.false()
expect(ctrlKey).to.be.false()
expect(altKey).to.be.false()
done()
})
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' })
@ -502,12 +500,12 @@ describe('webContents module', () => {
it('can send char events with modifiers', (done) => {
ipcMain.once('keypress', (event, key, code, keyCode, shiftKey, ctrlKey, altKey) => {
assert.strictEqual(key, 'Z')
assert.strictEqual(code, 'KeyZ')
assert.strictEqual(keyCode, 90)
assert.strictEqual(shiftKey, true)
assert.strictEqual(ctrlKey, true)
assert.strictEqual(altKey, false)
expect(key).to.equal('Z')
expect(code).to.equal('KeyZ')
expect(keyCode).to.equal(90)
expect(shiftKey).to.be.true()
expect(ctrlKey).to.be.true()
expect(altKey).to.be.false()
done()
})
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z' })
@ -530,18 +528,18 @@ describe('webContents module', () => {
describe('startDrag({file, icon})', () => {
it('throws errors for a missing file or a missing/empty icon', () => {
assert.throws(() => {
expect(() => {
w.webContents.startDrag({ icon: path.join(fixtures, 'assets', 'logo.png') })
}, /Must specify either 'file' or 'files' option/)
}).to.throw(`Must specify either 'file' or 'files' option`)
assert.throws(() => {
expect(() => {
w.webContents.startDrag({ file: __filename })
}, /Must specify 'icon' option/)
}).to.throw(`Must specify 'icon' option`)
if (process.platform === 'darwin') {
assert.throws(() => {
expect(() => {
w.webContents.startDrag({ file: __filename, icon: __filename })
}, /Must specify non-empty 'icon' option/)
}).to.throw(`Must specify non-empty 'icon' option`)
}
})
})
@ -550,8 +548,8 @@ describe('webContents module', () => {
describe('when the web contents is hidden', () => {
it('does not blur the focused window', (done) => {
ipcMain.once('answer', (event, parentFocused, childFocused) => {
assert.strictEqual(parentFocused, true)
assert.strictEqual(childFocused, false)
expect(parentFocused).to.be.true()
expect(childFocused).to.be.false()
done()
})
w.show()
@ -562,11 +560,10 @@ describe('webContents module', () => {
describe('getOSProcessId()', () => {
it('returns a valid procress id', async () => {
assert.strictEqual(w.webContents.getOSProcessId(), 0)
expect(w.webContents.getOSProcessId()).to.equal(0)
await w.loadURL('about:blank')
const pid = w.webContents.getOSProcessId()
expect(pid).to.be.above(0)
expect(w.webContents.getOSProcessId()).to.be.above(0)
})
})
@ -620,7 +617,7 @@ describe('webContents module', () => {
})
ipcMain.on('host1-zoom-level', (e, zoomLevel) => {
const expectedZoomLevel = hostZoomMap.host1
assert.strictEqual(zoomLevel, expectedZoomLevel)
expect(zoomLevel).to.equal(expectedZoomLevel)
if (finalNavigation) {
done()
} else {
@ -629,7 +626,7 @@ describe('webContents module', () => {
})
ipcMain.once('host2-zoom-level', (e, zoomLevel) => {
const expectedZoomLevel = hostZoomMap.host2
assert.strictEqual(zoomLevel, expectedZoomLevel)
expect(zoomLevel).to.equal(expectedZoomLevel)
finalNavigation = true
w.webContents.goBack()
})
@ -642,10 +639,10 @@ describe('webContents module', () => {
})
w2.webContents.on('did-finish-load', () => {
const zoomLevel1 = w.webContents.getZoomLevel()
assert.strictEqual(zoomLevel1, hostZoomMap.host3)
expect(zoomLevel1).to.equal(hostZoomMap.host3)
const zoomLevel2 = w2.webContents.getZoomLevel()
assert.strictEqual(zoomLevel1, zoomLevel2)
expect(zoomLevel1).to.equal(zoomLevel2)
w2.setClosable(true)
w2.close()
done()
@ -671,11 +668,11 @@ describe('webContents module', () => {
if (error) return done(error)
w2.webContents.on('did-finish-load', () => {
const zoomLevel1 = w.webContents.getZoomLevel()
assert.strictEqual(zoomLevel1, hostZoomMap.host3)
expect(zoomLevel1).to.equal(hostZoomMap.host3)
const zoomLevel2 = w2.webContents.getZoomLevel()
assert.strictEqual(zoomLevel2, 0)
assert.notStrictEqual(zoomLevel1, zoomLevel2)
expect(zoomLevel2).to.equal(0)
expect(zoomLevel1).to.not.equal(zoomLevel2)
protocol.unregisterProtocol(zoomScheme, (error) => {
if (error) return done(error)
@ -704,7 +701,7 @@ describe('webContents module', () => {
w.webContents.on('did-frame-finish-load', (e, isMainFrame) => {
if (!isMainFrame) {
const zoomLevel = w.webContents.getZoomLevel()
assert.strictEqual(zoomLevel, 2.0)
expect(zoomLevel).to.equal(2.0)
w.webContents.setZoomLevel(0)
server.close()
@ -725,11 +722,11 @@ describe('webContents module', () => {
})
w2.webContents.on('did-finish-load', () => {
const zoomLevel1 = w.webContents.getZoomLevel()
assert.strictEqual(zoomLevel1, finalZoomLevel)
expect(zoomLevel1).to.equal(finalZoomLevel)
const zoomLevel2 = w2.webContents.getZoomLevel()
assert.strictEqual(zoomLevel2, 0)
assert.notStrictEqual(zoomLevel1, zoomLevel2)
expect(zoomLevel2).to.equal(0)
expect(zoomLevel1).to.not.equal(zoomLevel2)
w2.setClosable(true)
w2.close()
@ -754,12 +751,12 @@ describe('webContents module', () => {
w.webContents.executeJavaScript(source)
} else {
const zoomLevel = w.webContents.getZoomLevel()
assert.strictEqual(zoomLevel, 0)
expect(zoomLevel).to.equal(0)
done()
}
})
ipcMain.once('zoom-level-set', (e, zoomLevel) => {
assert.strictEqual(zoomLevel, 0.6)
expect(zoomLevel).to.equal(0.6)
w.loadFile(path.join(fixtures, 'pages', 'd.html'))
initialNavigation = false
})
@ -777,7 +774,7 @@ describe('webContents module', () => {
]
policies.forEach((policy) => {
w.webContents.setWebRTCIPHandlingPolicy(policy)
assert.strictEqual(w.webContents.getWebRTCIPHandlingPolicy(), policy)
expect(w.webContents.getWebRTCIPHandlingPolicy()).to.equal(policy)
})
})
})
@ -788,7 +785,7 @@ describe('webContents module', () => {
done()
})
w.webContents.on('will-prevent-unload', (e) => {
assert.fail('should not have fired')
expect.fail('should not have fired')
})
w.loadFile(path.join(fixtures, 'api', 'close-beforeunload-undefined.html'))
})
@ -840,7 +837,7 @@ describe('webContents module', () => {
it('does not emit current-render-view-deleted when speculative RVHs are deleted', (done) => {
let currentRenderViewDeletedEmitted = false
w.webContents.once('destroyed', () => {
assert.strictEqual(currentRenderViewDeletedEmitted, false, 'current-render-view-deleted was emitted')
expect(currentRenderViewDeletedEmitted).to.be.false('current-render-view-deleted was emitted')
done()
})
const renderViewDeletedHandler = () => {
@ -857,7 +854,7 @@ describe('webContents module', () => {
it('emits current-render-view-deleted if the current RVHs are deleted', (done) => {
let currentRenderViewDeletedEmitted = false
w.webContents.once('destroyed', () => {
assert.strictEqual(currentRenderViewDeletedEmitted, true, 'current-render-view-deleted wasn\'t emitted')
expect(currentRenderViewDeletedEmitted).to.be.true('current-render-view-deleted wasn\'t emitted')
done()
})
w.webContents.on('current-render-view-deleted', () => {
@ -873,7 +870,7 @@ describe('webContents module', () => {
let rvhDeletedCount = 0
w.webContents.once('destroyed', () => {
const expectedRenderViewDeletedEventCount = 3 // 1 speculative upon redirection + 2 upon window close.
assert.strictEqual(rvhDeletedCount, expectedRenderViewDeletedEventCount, 'render-view-deleted wasn\'t emitted the expected nr. of times')
expect(rvhDeletedCount).to.equal(expectedRenderViewDeletedEventCount, 'render-view-deleted wasn\'t emitted the expected nr. of times')
done()
})
w.webContents.on('render-view-deleted', () => {
@ -888,8 +885,10 @@ describe('webContents module', () => {
describe('setIgnoreMenuShortcuts(ignore)', () => {
it('does not throw', () => {
assert.strictEqual(w.webContents.setIgnoreMenuShortcuts(true), undefined)
assert.strictEqual(w.webContents.setIgnoreMenuShortcuts(false), undefined)
expect(() => {
w.webContents.setIgnoreMenuShortcuts(true)
w.webContents.setIgnoreMenuShortcuts(false)
}).to.not.throw()
})
})
@ -975,10 +974,10 @@ describe('webContents module', () => {
w.webContents.on('did-change-theme-color', (e, color) => {
if (count === 0) {
count += 1
assert.strictEqual(color, '#FFEEDD')
expect(color).to.equal('#FFEEDD')
w.loadFile(path.join(fixtures, 'pages', 'base-page.html'))
} else if (count === 1) {
assert.strictEqual(color, null)
expect(color).to.be.null()
done()
}
})
@ -1030,7 +1029,7 @@ describe('webContents module', () => {
it('propagates referrer information to new target=_blank windows', (done) => {
const server = http.createServer((req, res) => {
if (req.url === '/should_have_referrer') {
assert.strictEqual(req.headers.referer, 'http://127.0.0.1:' + server.address().port + '/')
expect(req.headers.referer).to.equal(`http://127.0.0.1:${server.address().port}/`)
return done()
}
res.end('<a id="a" href="/should_have_referrer" target="_blank">link</a>')
@ -1039,8 +1038,8 @@ describe('webContents module', () => {
const url = 'http://127.0.0.1:' + server.address().port + '/'
w.webContents.once('did-finish-load', () => {
w.webContents.once('new-window', (event, newUrl, frameName, disposition, options, features, referrer) => {
assert.strictEqual(referrer.url, url)
assert.strictEqual(referrer.policy, 'no-referrer-when-downgrade')
expect(referrer.url).to.equal(url)
expect(referrer.policy).to.equal('no-referrer-when-downgrade')
})
w.webContents.executeJavaScript('a.click()')
})
@ -1053,7 +1052,7 @@ describe('webContents module', () => {
xit('propagates referrer information to windows opened with window.open', (done) => {
const server = http.createServer((req, res) => {
if (req.url === '/should_have_referrer') {
assert.strictEqual(req.headers.referer, 'http://127.0.0.1:' + server.address().port + '/')
expect(req.headers.referer).to.equal(`http://127.0.0.1:${server.address().port}/`)
return done()
}
res.end('')
@ -1062,8 +1061,8 @@ describe('webContents module', () => {
const url = 'http://127.0.0.1:' + server.address().port + '/'
w.webContents.once('did-finish-load', () => {
w.webContents.once('new-window', (event, newUrl, frameName, disposition, options, features, referrer) => {
assert.strictEqual(referrer.url, url)
assert.strictEqual(referrer.policy, 'no-referrer-when-downgrade')
expect(referrer.url).to.equal(url)
expect(referrer.policy).to.equal('no-referrer-when-downgrade')
})
w.webContents.executeJavaScript('window.open(location.href + "should_have_referrer")')
})
@ -1083,7 +1082,7 @@ describe('webContents module', () => {
})
await w.loadURL('about:blank')
const result = await w.webContents.executeJavaScript('37 + 5')
assert.strictEqual(result, 42)
expect(result).to.equal(42)
})
})
@ -1280,7 +1279,7 @@ describe('webContents module', () => {
})
await w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E')
const printers = w.webContents.getPrinters()
assert.strictEqual(Array.isArray(printers), true)
expect(printers).to.be.an('array')
})
})
@ -1304,8 +1303,7 @@ describe('webContents module', () => {
})
await w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E')
const data = await w.webContents.printToPDF({})
assert.strictEqual(data instanceof Buffer, true)
assert.notStrictEqual(data.length, 0)
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty()
})
})
})

View file

@ -1,6 +1,5 @@
'use strict'
const assert = require('assert')
const chai = require('chai')
const ChildProcess = require('child_process')
const dirtyChai = require('dirty-chai')
@ -28,9 +27,9 @@ describe('WebContentsView', () => {
const web = webContents.create({})
w = new TopLevelWindow({ show: false })
w.setContentView(new WebContentsView(web))
assert.throws(() => {
expect(() => {
w.setContentView(new WebContentsView(web))
}, /The WebContents has already been added to a View/)
}).to.throw('The WebContents has already been added to a View')
})
describe('new WebContentsView()', () => {

View file

@ -1,4 +1,3 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const path = require('path')
@ -21,10 +20,10 @@ describe('webFrame module', function () {
})
it('supports setting the visual and layout zoom level limits', function () {
assert.doesNotThrow(function () {
expect(() => {
webFrame.setVisualZoomLevelLimits(1, 50)
webFrame.setLayoutZoomLevelLimits(0, 25)
})
}).to.not.throw()
})
it('calls a spellcheck provider', async () => {

View file

@ -1,9 +1,14 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const http = require('http')
const qs = require('querystring')
const remote = require('electron').remote
const session = remote.session
const { expect } = chai
chai.use(dirtyChai)
/* The whole webRequest API doesn't use standard callbacks */
/* eslint-disable standard/no-callback-literal */
@ -67,7 +72,7 @@ describe('webRequest module', () => {
$.ajax({
url: `${defaultURL}nofilter/test`,
success: (data) => {
assert.strictEqual(data, '/nofilter/test')
expect(data).to.equal('/nofilter/test')
$.ajax({
url: `${defaultURL}filter/test`,
success: () => done('unexpected success'),
@ -80,19 +85,19 @@ describe('webRequest module', () => {
it('receives details object', (done) => {
ses.webRequest.onBeforeRequest((details, callback) => {
assert.strictEqual(typeof details.id, 'number')
assert.strictEqual(typeof details.timestamp, 'number')
assert.strictEqual(typeof details.webContentsId, 'number')
assert.strictEqual(details.url, defaultURL)
assert.strictEqual(details.method, 'GET')
assert.strictEqual(details.resourceType, 'xhr')
assert(!details.uploadData)
expect(details.id).to.be.a('number')
expect(details.timestamp).to.be.a('number')
expect(details.webContentsId).to.be.a('number')
expect(details.url).to.be.a('string').that.is.equal(defaultURL)
expect(details.method).to.be.a('string').that.is.equal('GET')
expect(details.resourceType).to.be.a('string').that.is.equal('xhr')
expect(details.uploadData).to.be.undefined()
callback({})
})
$.ajax({
url: defaultURL,
success: (data) => {
assert.strictEqual(data, '/')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -105,11 +110,11 @@ describe('webRequest module', () => {
type: 'string'
}
ses.webRequest.onBeforeRequest((details, callback) => {
assert.strictEqual(details.url, defaultURL)
assert.strictEqual(details.method, 'POST')
assert.strictEqual(details.uploadData.length, 1)
expect(details.url).to.equal(defaultURL)
expect(details.method).to.equal('POST')
expect(details.uploadData).to.have.lengthOf(1)
const data = qs.parse(details.uploadData[0].bytes.toString())
assert.deepStrictEqual({ ...data }, postData)
expect(data).to.deep.equal(postData)
callback({ cancel: true })
})
$.ajax({
@ -132,7 +137,7 @@ describe('webRequest module', () => {
$.ajax({
url: defaultURL,
success: (data) => {
assert.strictEqual(data, '/redirect')
expect(data).to.equal('/redirect')
done()
},
error: (xhr, errorType) => done(errorType)
@ -147,15 +152,15 @@ describe('webRequest module', () => {
it('receives details object', (done) => {
ses.webRequest.onBeforeSendHeaders((details, callback) => {
assert.strictEqual(typeof details.requestHeaders, 'object')
assert.strictEqual(details.requestHeaders['Foo.Bar'], 'baz')
expect(details.requestHeaders).to.be.an('object')
expect(details.requestHeaders['Foo.Bar']).to.equal('baz')
callback({})
})
$.ajax({
url: defaultURL,
headers: { 'Foo.Bar': 'baz' },
success: (data) => {
assert.strictEqual(data, '/')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -171,7 +176,7 @@ describe('webRequest module', () => {
$.ajax({
url: defaultURL,
success: (data) => {
assert.strictEqual(data, '/header/received')
expect(data).to.equal('/header/received')
done()
},
error: (xhr, errorType) => done(errorType)
@ -186,7 +191,7 @@ describe('webRequest module', () => {
callback({ requestHeaders: requestHeaders })
})
ses.webRequest.onSendHeaders((details) => {
assert.deepStrictEqual(details.requestHeaders, requestHeaders)
expect(details.requestHeaders).to.deep.equal(requestHeaders)
done()
})
$.ajax({
@ -203,12 +208,12 @@ describe('webRequest module', () => {
it('receives details object', (done) => {
ses.webRequest.onSendHeaders((details) => {
assert.strictEqual(typeof details.requestHeaders, 'object')
expect(details.requestHeaders).to.be.an('object')
})
$.ajax({
url: defaultURL,
success: (data) => {
assert.strictEqual(data, '/')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -223,15 +228,15 @@ describe('webRequest module', () => {
it('receives details object', (done) => {
ses.webRequest.onHeadersReceived((details, callback) => {
assert.strictEqual(details.statusLine, 'HTTP/1.1 200 OK')
assert.strictEqual(details.statusCode, 200)
assert.deepStrictEqual(details.responseHeaders['Custom'], ['Header'])
expect(details.statusLine).to.equal('HTTP/1.1 200 OK')
expect(details.statusCode).to.equal(200)
expect(details.responseHeaders['Custom']).to.deep.equal(['Header'])
callback({})
})
$.ajax({
url: defaultURL,
success: (data) => {
assert.strictEqual(data, '/')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -247,8 +252,8 @@ describe('webRequest module', () => {
$.ajax({
url: defaultURL,
success: (data, status, xhr) => {
assert.strictEqual(xhr.getResponseHeader('Custom'), 'Changed')
assert.strictEqual(data, '/')
expect(xhr.getResponseHeader('Custom')).to.equal('Changed')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -262,8 +267,8 @@ describe('webRequest module', () => {
$.ajax({
url: defaultURL,
success: (data, status, xhr) => {
assert.strictEqual(xhr.getResponseHeader('Custom'), 'Header')
assert.strictEqual(data, '/')
expect(xhr.getResponseHeader('Custom')).to.equal('Header')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -278,7 +283,7 @@ describe('webRequest module', () => {
$.ajax({
url: defaultURL + 'serverRedirect',
success: (data, status, xhr) => {
assert.strictEqual(xhr.getResponseHeader('Custom'), 'Header')
expect(xhr.getResponseHeader('Custom')).to.equal('Header')
done()
},
error: (xhr, errorType) => done(errorType)
@ -297,7 +302,7 @@ describe('webRequest module', () => {
url: defaultURL,
success: (data, status, xhr) => {},
error: (xhr, errorType) => {
assert.strictEqual(xhr.getResponseHeader('Custom'), 'Header')
expect(xhr.getResponseHeader('Custom')).to.equal('Header')
done()
}
})
@ -311,16 +316,16 @@ describe('webRequest module', () => {
it('receives details object', (done) => {
ses.webRequest.onResponseStarted((details) => {
assert.strictEqual(typeof details.fromCache, 'boolean')
assert.strictEqual(details.statusLine, 'HTTP/1.1 200 OK')
assert.strictEqual(details.statusCode, 200)
assert.deepStrictEqual(details.responseHeaders['Custom'], ['Header'])
expect(details.fromCache).to.be.a('boolean')
expect(details.statusLine).to.equal('HTTP/1.1 200 OK')
expect(details.statusCode).to.equal(200)
expect(details.responseHeaders['Custom']).to.deep.equal(['Header'])
})
$.ajax({
url: defaultURL,
success: (data, status, xhr) => {
assert.strictEqual(xhr.getResponseHeader('Custom'), 'Header')
assert.strictEqual(data, '/')
expect(xhr.getResponseHeader('Custom')).to.equal('Header')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -344,15 +349,15 @@ describe('webRequest module', () => {
}
})
ses.webRequest.onBeforeRedirect((details) => {
assert.strictEqual(typeof details.fromCache, 'boolean')
assert.strictEqual(details.statusLine, 'HTTP/1.1 307 Internal Redirect')
assert.strictEqual(details.statusCode, 307)
assert.strictEqual(details.redirectURL, redirectURL)
expect(details.fromCache).to.be.a('boolean')
expect(details.statusLine).to.equal('HTTP/1.1 307 Internal Redirect')
expect(details.statusCode).to.equal(307)
expect(details.redirectURL).to.equal(redirectURL)
})
$.ajax({
url: defaultURL,
success: (data) => {
assert.strictEqual(data, '/redirect')
expect(data).to.equal('/redirect')
done()
},
error: (xhr, errorType) => done(errorType)
@ -367,14 +372,14 @@ describe('webRequest module', () => {
it('receives details object', (done) => {
ses.webRequest.onCompleted((details) => {
assert.strictEqual(typeof details.fromCache, 'boolean')
assert.strictEqual(details.statusLine, 'HTTP/1.1 200 OK')
assert.strictEqual(details.statusCode, 200)
expect(details.fromCache).to.be.a('boolean')
expect(details.statusLine).to.equal('HTTP/1.1 200 OK')
expect(details.statusCode).to.equal(200)
})
$.ajax({
url: defaultURL,
success: (data) => {
assert.strictEqual(data, '/')
expect(data).to.equal('/')
done()
},
error: (xhr, errorType) => done(errorType)
@ -393,7 +398,7 @@ describe('webRequest module', () => {
callback({ cancel: true })
})
ses.webRequest.onErrorOccurred((details) => {
assert.strictEqual(details.error, 'net::ERR_BLOCKED_BY_CLIENT')
expect(details.error).to.equal('net::ERR_BLOCKED_BY_CLIENT')
done()
})
$.ajax({

File diff suppressed because it is too large Load diff

View file

@ -46,7 +46,7 @@ describe('chrome api', () => {
const manifest = JSON.parse(manifestString)
expect(manifest.name).to.equal(actualManifest.name)
expect(manifest.content_scripts.length).to.equal(actualManifest.content_scripts.length)
expect(manifest.content_scripts).to.have.lengthOf(actualManifest.content_scripts.length)
})
it('chrome.tabs.sendMessage receives the response', async function () {

View file

@ -1,4 +1,3 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const fs = require('fs')
@ -10,7 +9,7 @@ const ChildProcess = require('child_process')
const { ipcRenderer, remote } = require('electron')
const { emittedOnce } = require('./events-helpers')
const { closeWindow, waitForWebContentsToLoad } = require('./window-helpers')
const { resolveGetters } = require('./assert-helpers')
const { resolveGetters } = require('./expect-helpers')
const { app, BrowserWindow, ipcMain, protocol, session, webContents } = remote
const isCI = remote.getGlobal('isCi')
const features = process.electronBinding('features')
@ -45,7 +44,7 @@ describe('chromium feature', () => {
appProcess.stdout.on('data', (data) => { output += data })
appProcess.stdout.on('end', () => {
output = output.replace(/(\r\n|\n|\r)/gm, '')
assert.strictEqual(output, result)
expect(output).to.equal(result)
done()
})
}
@ -178,7 +177,7 @@ describe('chromium feature', () => {
w.webContents.on('ipc-message', (event, channel, deviceId) => {
if (channel === 'deviceIds') deviceIds.push(deviceId)
if (deviceIds.length === 2) {
assert.notDeepStrictEqual(deviceIds[0], deviceIds[1])
expect(deviceIds[0]).to.not.deep.equal(deviceIds[1])
closeWindow(w).then(() => {
w = null
done()
@ -195,15 +194,14 @@ describe('chromium feature', () => {
describe('navigator.language', () => {
it('should not be empty', () => {
assert.notStrictEqual(navigator.language, '')
expect(navigator.language).to.not.equal('')
})
})
describe('navigator.languages', (done) => {
it('should return the system locale only', () => {
const appLocale = app.getLocale()
assert.strictEqual(navigator.languages.length, 1)
assert.strictEqual(navigator.languages[0], appLocale)
expect(navigator.languages).to.deep.equal([appLocale])
})
})
@ -222,7 +220,7 @@ describe('chromium feature', () => {
} else if (channel === 'error') {
done(message)
} else if (channel === 'response') {
assert.strictEqual(message, 'Hello from serviceWorker!')
expect(message).to.equal('Hello from serviceWorker!')
session.fromPartition('sw-file-scheme-spec').clearStorageData({
storages: ['serviceworkers']
}).then(() => done())
@ -261,7 +259,7 @@ describe('chromium feature', () => {
} else if (channel === 'error') {
done(`unexpected error : ${message}`)
} else if (channel === 'response') {
assert.strictEqual(message, 'Hello from serviceWorker!')
expect(message).to.equal('Hello from serviceWorker!')
customSession.clearStorageData({
storages: ['serviceworkers']
}).then(() => {
@ -283,7 +281,8 @@ describe('chromium feature', () => {
it('returns position when permission is granted', (done) => {
navigator.geolocation.getCurrentPosition((position) => {
assert(position.timestamp)
expect(position).to.have.a.property('coords')
expect(position).to.have.a.property('timestamp')
done()
}, (error) => {
done(error)
@ -319,15 +318,15 @@ describe('chromium feature', () => {
describe('window.open', () => {
it('returns a BrowserWindowProxy object', () => {
const b = window.open('about:blank', '', 'show=no')
assert.strictEqual(b.closed, false)
assert.strictEqual(b.constructor.name, 'BrowserWindowProxy')
expect(b.closed).to.be.false()
expect(b.constructor.name).to.equal('BrowserWindowProxy')
b.close()
})
it('accepts "nodeIntegration" as feature', (done) => {
let b = null
listener = (event) => {
assert.strictEqual(event.data.isProcessGlobalUndefined, true)
expect(event.data.isProcessGlobalUndefined).to.be.true()
b.close()
done()
}
@ -341,7 +340,7 @@ describe('chromium feature', () => {
const ref1 = remote.getCurrentWindow().getSize()
const width = ref1[0]
const height = ref1[1]
assert.strictEqual(event.data, `size: ${width} ${height}`)
expect(event.data).to.equal(`size: ${width} ${height}`)
b.close()
done()
}
@ -361,7 +360,7 @@ describe('chromium feature', () => {
}
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
assert.strictEqual(options.show, w.isVisible())
expect(options.show).to.equal(w.isVisible())
w.close()
done()
})
@ -372,7 +371,7 @@ describe('chromium feature', () => {
it('disables node integration when it is disabled on the parent window', (done) => {
let b = null
listener = (event) => {
assert.strictEqual(event.data.isProcessGlobalUndefined, true)
expect(event.data.isProcessGlobalUndefined).to.be.true()
b.close()
done()
}
@ -395,7 +394,7 @@ describe('chromium feature', () => {
app.once('web-contents-created', (event, contents) => {
contents.once('did-finish-load', () => {
contents.executeJavaScript('typeof process').then((typeofProcessGlobal) => {
assert.strictEqual(typeofProcessGlobal, 'undefined')
expect(typeofProcessGlobal).to.equal('undefined')
b.close()
done()
}).catch(done)
@ -410,7 +409,7 @@ describe('chromium feature', () => {
contents.once('did-finish-load', () => {
app.once('browser-window-created', (event, window) => {
const preferences = window.webContents.getLastWebPreferences()
assert.strictEqual(preferences.javascript, false)
expect(preferences.javascript).to.be.false()
window.destroy()
b.close()
done()
@ -432,7 +431,7 @@ describe('chromium feature', () => {
it('disables the <webview> tag when it is disabled on the parent window', (done) => {
let b = null
listener = (event) => {
assert.strictEqual(event.data.isWebViewGlobalUndefined, true)
expect(event.data.isWebViewGlobalUndefined).to.be.true()
b.close()
done()
}
@ -456,7 +455,7 @@ describe('chromium feature', () => {
height: 450
}
listener = (event) => {
assert.strictEqual(event.data, `size: ${size.width} ${size.height}`)
expect(event.data).to.equal(`size: ${size.width} ${size.height}`)
b.close()
done()
}
@ -468,8 +467,8 @@ describe('chromium feature', () => {
w = BrowserWindow.fromId(ipcRenderer.sendSync('create-window-with-options-cycle'))
w.loadFile(path.join(fixtures, 'pages', 'window-open.html'))
w.webContents.once('new-window', (event, url, frameName, disposition, options) => {
assert.strictEqual(options.show, false)
assert.deepStrictEqual(...resolveGetters(options.foo, {
expect(options.show).to.be.false()
expect(...resolveGetters(options.foo)).to.deep.equal({
bar: undefined,
baz: {
hello: {
@ -481,7 +480,7 @@ describe('chromium feature', () => {
world: true
}
}
}))
})
done()
})
})
@ -496,7 +495,7 @@ describe('chromium feature', () => {
}
app.once('browser-window-created', (event, window) => {
window.webContents.once('did-finish-load', () => {
assert.strictEqual(b.location.href, targetURL)
expect(b.location.href).to.equal(targetURL)
b.close()
done()
})
@ -526,7 +525,7 @@ describe('chromium feature', () => {
try {
const [, { webContents }] = await browserWindowCreated
await waitForWebContentsToLoad(webContents)
assert.strictEqual(w.location.href, 'about:blank')
expect(w.location.href).to.equal('about:blank')
} finally {
w.close()
}
@ -538,26 +537,26 @@ describe('chromium feature', () => {
try {
const [, { webContents }] = await browserWindowCreated
await waitForWebContentsToLoad(webContents)
assert.strictEqual(w.location.href, 'about:blank')
expect(w.location.href).to.equal('about:blank')
} finally {
w.close()
}
})
it('throws an exception when the arguments cannot be converted to strings', () => {
assert.throws(() => {
expect(() => {
window.open('', { toString: null })
}, /Cannot convert object to primitive value/)
}).to.throw('Cannot convert object to primitive value')
assert.throws(() => {
expect(() => {
window.open('', '', { toString: 3 })
}, /Cannot convert object to primitive value/)
}).to.throw('Cannot convert object to primitive value')
})
it('sets the window title to the specified frameName', (done) => {
let b = null
app.once('browser-window-created', (event, createdWindow) => {
assert.strictEqual(createdWindow.getTitle(), 'hello')
expect(createdWindow.getTitle()).to.equal('hello')
b.close()
done()
})
@ -567,7 +566,7 @@ describe('chromium feature', () => {
it('does not throw an exception when the frameName is a built-in object property', (done) => {
let b = null
app.once('browser-window-created', (event, createdWindow) => {
assert.strictEqual(createdWindow.getTitle(), '__proto__')
expect(createdWindow.getTitle()).to.equal('__proto__')
b.close()
done()
})
@ -576,9 +575,9 @@ describe('chromium feature', () => {
it('does not throw an exception when the features include webPreferences', () => {
let b = null
assert.doesNotThrow(() => {
expect(() => {
b = window.open('', '', 'webPreferences=')
})
}).to.not.throw()
b.close()
})
})
@ -602,7 +601,7 @@ describe('chromium feature', () => {
it('is not null for window opened by window.open', (done) => {
let b = null
listener = (event) => {
assert.strictEqual(event.data, 'object')
expect(event.data).to.equal('object')
b.close()
done()
}
@ -632,7 +631,7 @@ describe('chromium feature', () => {
it('does nothing when origin of current window does not match opener', (done) => {
listener = (event) => {
assert.strictEqual(event.data, '')
expect(event.data).to.equal('')
done()
}
window.addEventListener('message', listener)
@ -641,7 +640,7 @@ describe('chromium feature', () => {
it('works when origin matches', (done) => {
listener = (event) => {
assert.strictEqual(event.data, location.href)
expect(event.data).to.equal(location.href)
done()
}
window.addEventListener('message', listener)
@ -650,7 +649,7 @@ describe('chromium feature', () => {
it('works when origin does not match opener but has node integration', (done) => {
listener = (event) => {
assert.strictEqual(event.data, location.href)
expect(event.data).to.equal(location.href)
done()
}
window.addEventListener('message', listener)
@ -681,7 +680,7 @@ describe('chromium feature', () => {
it('does nothing when origin of webview src URL does not match opener', (done) => {
webview = new WebView()
webview.addEventListener('console-message', (e) => {
assert.strictEqual(e.message, '')
expect(e.message).to.equal('')
done()
})
webview.setAttribute('allowpopups', 'on')
@ -699,7 +698,7 @@ describe('chromium feature', () => {
it('works when origin matches', (done) => {
webview = new WebView()
webview.addEventListener('console-message', (e) => {
assert.strictEqual(e.message, webview.src)
expect(e.message).to.equal(webview.src)
done()
})
webview.setAttribute('allowpopups', 'on')
@ -718,7 +717,7 @@ describe('chromium feature', () => {
webview = new WebView()
webview.addEventListener('console-message', (e) => {
webview.remove()
assert.strictEqual(e.message, webview.src)
expect(e.message).to.equal(webview.src)
done()
})
webview.setAttribute('allowpopups', 'on')
@ -742,10 +741,10 @@ describe('chromium feature', () => {
window.removeEventListener('message', listener)
b.close()
const message = JSON.parse(event.data)
assert.strictEqual(message.data, 'testing')
assert.strictEqual(message.origin, 'file://')
assert.strictEqual(message.sourceEqualsOpener, true)
assert.strictEqual(event.origin, 'file://')
expect(message.data).to.equal('testing')
expect(message.origin).to.equal('file://')
expect(message.sourceEqualsOpener).to.be.true()
expect(event.origin).to.equal('file://')
done()
}
window.addEventListener('message', listener)
@ -759,9 +758,9 @@ describe('chromium feature', () => {
it('throws an exception when the targetOrigin cannot be converted to a string', () => {
const b = window.open('')
assert.throws(() => {
expect(() => {
b.postMessage('test', { toString: null })
}, /Cannot convert object to primitive value/)
}).to.throw('Cannot convert object to primitive value')
b.close()
})
})
@ -772,8 +771,8 @@ describe('chromium feature', () => {
listener = (event) => {
window.removeEventListener('message', listener)
b.close()
assert.strictEqual(event.source, b)
assert.strictEqual(event.origin, 'file://')
expect(event.source).to.equal(b)
expect(event.origin).to.equal('file://')
done()
}
window.addEventListener('message', listener)
@ -784,7 +783,7 @@ describe('chromium feature', () => {
const webview = new WebView()
webview.addEventListener('console-message', (e) => {
webview.remove()
assert.strictEqual(e.message, 'message')
expect(e.message).to.equal('message')
done()
})
webview.allowpopups = true
@ -824,7 +823,7 @@ describe('chromium feature', () => {
listener = (event) => {
window.removeEventListener('message', listener)
b.close()
assert.strictEqual(event.data, 'deliver')
expect(event.data).to.equal('deliver')
done()
}
window.addEventListener('message', listener)
@ -837,7 +836,6 @@ describe('chromium feature', () => {
it('does not crash', () => {
const RUint8Array = remote.getGlobal('Uint8Array')
const arr = new RUint8Array()
assert(arr)
})
})
@ -856,7 +854,7 @@ describe('chromium feature', () => {
}
const webgl = document.createElement('canvas').getContext('webgl')
assert.notStrictEqual(webgl, null)
expect(webgl).to.not.be.null()
})
})
@ -865,7 +863,7 @@ describe('chromium feature', () => {
const worker = new Worker('../fixtures/workers/worker.js')
const message = 'ping'
worker.onmessage = (event) => {
assert.strictEqual(event.data, message)
expect(event.data).to.equal(message)
worker.terminate()
done()
}
@ -875,7 +873,7 @@ describe('chromium feature', () => {
it('Worker has no node integration by default', (done) => {
const worker = new Worker('../fixtures/workers/worker_node.js')
worker.onmessage = (event) => {
assert.strictEqual(event.data, 'undefined undefined undefined undefined')
expect(event.data).to.equal('undefined undefined undefined undefined')
worker.terminate()
done()
}
@ -884,7 +882,7 @@ describe('chromium feature', () => {
it('Worker has node integration with nodeIntegrationInWorker', (done) => {
const webview = new WebView()
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'object function object function')
expect(e.channel).to.equal('object function object function')
webview.remove()
done()
})
@ -897,7 +895,7 @@ describe('chromium feature', () => {
const worker = new SharedWorker('../fixtures/workers/shared_worker.js')
const message = 'ping'
worker.port.onmessage = (event) => {
assert.strictEqual(event.data, message)
expect(event.data).to.equal(message)
done()
}
worker.port.postMessage(message)
@ -906,7 +904,7 @@ describe('chromium feature', () => {
it('SharedWorker has no node integration by default', (done) => {
const worker = new SharedWorker('../fixtures/workers/shared_worker_node.js')
worker.port.onmessage = (event) => {
assert.strictEqual(event.data, 'undefined undefined undefined undefined')
expect(event.data).to.equal('undefined undefined undefined undefined')
done()
}
})
@ -917,7 +915,7 @@ describe('chromium feature', () => {
console.log(e)
})
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'object function object function')
expect(e.channel).to.equal('object function object function')
webview.remove()
done()
})
@ -942,7 +940,7 @@ describe('chromium feature', () => {
iframe.src = `file://${fixtures}/pages/set-global.html`
document.body.appendChild(iframe)
iframe.onload = () => {
assert.strictEqual(iframe.contentWindow.test, 'undefined undefined undefined')
expect(iframe.contentWindow.test).to.equal('undefined undefined undefined')
done()
}
})
@ -965,7 +963,7 @@ describe('chromium feature', () => {
it('requesting persitent quota works', (done) => {
navigator.webkitPersistentStorage.requestQuota(1024 * 1024, (grantedBytes) => {
assert.strictEqual(grantedBytes, 1048576)
expect(grantedBytes).to.equal(1048576)
done()
})
})
@ -1006,10 +1004,8 @@ describe('chromium feature', () => {
})
it('cannot access localStorage', (done) => {
ipcMain.once('local-storage-response', (event, message) => {
assert.strictEqual(
message,
'Failed to read the \'localStorage\' property from \'Window\': Access is denied for this document.')
ipcMain.once('local-storage-response', (event, error) => {
expect(error).to.equal(`Failed to read the 'localStorage' property from 'Window': Access is denied for this document.`)
done()
})
contents.loadURL(protocolName + '://host/localStorage')
@ -1017,9 +1013,7 @@ describe('chromium feature', () => {
it('cannot access sessionStorage', (done) => {
ipcMain.once('session-storage-response', (event, error) => {
assert.strictEqual(
error,
'Failed to read the \'sessionStorage\' property from \'Window\': Access is denied for this document.')
expect(error).to.equal(`Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document.`)
done()
})
contents.loadURL(`${protocolName}://host/sessionStorage`)
@ -1027,9 +1021,7 @@ describe('chromium feature', () => {
it('cannot access WebSQL database', (done) => {
ipcMain.once('web-sql-response', (event, error) => {
assert.strictEqual(
error,
'Failed to execute \'openDatabase\' on \'Window\': Access to the WebDatabase API is denied in this context.')
expect(error).to.equal(`Failed to execute 'openDatabase' on 'Window': Access to the WebDatabase API is denied in this context.`)
done()
})
contents.loadURL(`${protocolName}://host/WebSQL`)
@ -1037,9 +1029,7 @@ describe('chromium feature', () => {
it('cannot access indexedDB', (done) => {
ipcMain.once('indexed-db-response', (event, error) => {
assert.strictEqual(
error,
'Failed to execute \'open\' on \'IDBFactory\': access to the Indexed Database API is denied in this context.')
expect(error).to.equal(`Failed to execute 'open' on 'IDBFactory': access to the Indexed Database API is denied in this context.`)
done()
})
contents.loadURL(`${protocolName}://host/indexedDB`)
@ -1047,9 +1037,7 @@ describe('chromium feature', () => {
it('cannot access cookie', (done) => {
ipcMain.once('cookie-response', (event, error) => {
assert.strictEqual(
error,
'Failed to set the \'cookie\' property on \'Document\': Access is denied for this document.')
expect(error).to.equal(`Failed to set the 'cookie' property on 'Document': Access is denied for this document.`)
done()
})
contents.loadURL(`${protocolName}://host/cookie`)
@ -1093,14 +1081,14 @@ describe('chromium feature', () => {
})
let redirected = false
w.webContents.on('crashed', () => {
assert.fail('renderer crashed / was killed')
expect.fail('renderer crashed / was killed')
})
w.webContents.on('did-redirect-navigation', (event, url) => {
assert.strictEqual(url, `${server.cross_site_url}/redirected`)
expect(url).to.equal(`${server.cross_site_url}/redirected`)
redirected = true
})
w.webContents.on('did-finish-load', () => {
assert.strictEqual(redirected, true, 'didnt redirect')
expect(redirected).to.be.true('didnt redirect')
done()
})
w.loadURL(`${server.url}/redirect-cross-site`)
@ -1136,7 +1124,6 @@ describe('chromium feature', () => {
}
})
const socket = new WebSocket(`ws://127.0.0.1:${port}`)
assert(socket)
})
})
})
@ -1241,15 +1228,15 @@ describe('chromium feature', () => {
this.createBrowserWindow({ plugins: true, preload: preloadFile })
ipcMain.once('pdf-loaded', (event, state) => {
assert.strictEqual(state, 'success')
expect(state).to.equal('success')
done()
})
w.webContents.on('page-title-updated', () => {
const parsedURL = url.parse(w.webContents.getURL(), true)
assert.strictEqual(parsedURL.protocol, 'chrome:')
assert.strictEqual(parsedURL.hostname, 'pdf-viewer')
assert.strictEqual(parsedURL.query.src, pagePath)
assert.strictEqual(w.webContents.getTitle(), 'cat.pdf')
expect(parsedURL.protocol).to.equal('chrome:')
expect(parsedURL.hostname).to.equal('pdf-viewer')
expect(parsedURL.query.src).to.equal(pagePath)
expect(w.webContents.getTitle()).to.equal('cat.pdf')
})
w.loadFile(path.join(fixtures, 'pages', page))
}
@ -1258,15 +1245,15 @@ describe('chromium feature', () => {
it('opens when loading a pdf resource as top level navigation', (done) => {
this.createBrowserWindow({ plugins: true, preload: 'preload-pdf-loaded.js' })
ipcMain.once('pdf-loaded', (event, state) => {
assert.strictEqual(state, 'success')
expect(state).to.equal('success')
done()
})
w.webContents.on('page-title-updated', () => {
const parsedURL = url.parse(w.webContents.getURL(), true)
assert.strictEqual(parsedURL.protocol, 'chrome:')
assert.strictEqual(parsedURL.hostname, 'pdf-viewer')
assert.strictEqual(parsedURL.query.src, this.pdfSource)
assert.strictEqual(w.webContents.getTitle(), 'cat.pdf')
expect(parsedURL.protocol).to.equal('chrome:')
expect(parsedURL.hostname).to.equal('pdf-viewer')
expect(parsedURL.query.src).to.equal(this.pdfSource)
expect(w.webContents.getTitle()).to.equal('cat.pdf')
})
w.webContents.loadURL(this.pdfSource)
})
@ -1274,17 +1261,17 @@ describe('chromium feature', () => {
it('opens a pdf link given params, the query string should be escaped', (done) => {
this.createBrowserWindow({ plugins: true, preload: 'preload-pdf-loaded.js' })
ipcMain.once('pdf-loaded', (event, state) => {
assert.strictEqual(state, 'success')
expect(state).to.equal('success')
done()
})
w.webContents.on('page-title-updated', () => {
const parsedURL = url.parse(w.webContents.getURL(), true)
assert.strictEqual(parsedURL.protocol, 'chrome:')
assert.strictEqual(parsedURL.hostname, 'pdf-viewer')
assert.strictEqual(parsedURL.query.src, this.pdfSourceWithParams)
assert.strictEqual(parsedURL.query.b, undefined)
assert(parsedURL.search.endsWith('%3Fa%3D1%26b%3D2'))
assert.strictEqual(w.webContents.getTitle(), 'cat.pdf')
expect(parsedURL.protocol).to.equal('chrome:')
expect(parsedURL.hostname).to.equal('pdf-viewer')
expect(parsedURL.query.src).to.equal(this.pdfSourceWithParams)
expect(parsedURL.query.b).to.be.undefined()
expect(parsedURL.search.endsWith('%3Fa%3D1%26b%3D2')).to.be.true()
expect(w.webContents.getTitle()).to.equal('cat.pdf')
})
w.webContents.loadURL(this.pdfSourceWithParams)
})
@ -1293,9 +1280,9 @@ describe('chromium feature', () => {
this.createBrowserWindow({ plugins: false, preload: 'preload-pdf-loaded.js' })
ipcRenderer.sendSync('set-download-option', false, false)
ipcRenderer.once('download-done', (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) => {
assert.strictEqual(state, 'completed')
assert.strictEqual(filename, 'cat.pdf')
assert.strictEqual(mimeType, 'application/pdf')
expect(state).to.equal('completed')
expect(filename).to.equal('cat.pdf')
expect(mimeType).to.equal('application/pdf')
fs.unlinkSync(path.join(fixtures, 'mock.pdf'))
done()
})
@ -1304,8 +1291,8 @@ describe('chromium feature', () => {
it('should not open when pdf is requested as sub resource', (done) => {
fetch(this.pdfSource).then((res) => {
assert.strictEqual(res.status, 200)
assert.notStrictEqual(document.title, 'cat.pdf')
expect(res.status).to.equal(200)
expect(document.title).to.not.equal('cat.pdf')
done()
}).catch((e) => done(e))
})
@ -1321,26 +1308,26 @@ describe('chromium feature', () => {
describe('window.alert(message, title)', () => {
it('throws an exception when the arguments cannot be converted to strings', () => {
assert.throws(() => {
expect(() => {
window.alert({ toString: null })
}, /Cannot convert object to primitive value/)
}).to.throw('Cannot convert object to primitive value')
})
})
describe('window.confirm(message, title)', () => {
it('throws an exception when the arguments cannot be converted to strings', () => {
assert.throws(() => {
expect(() => {
window.confirm({ toString: null }, 'title')
}, /Cannot convert object to primitive value/)
}).to.throw('Cannot convert object to primitive value')
})
})
describe('window.history', () => {
describe('window.history.go(offset)', () => {
it('throws an exception when the argumnet cannot be converted to a string', () => {
assert.throws(() => {
expect(() => {
window.history.go({ toString: null })
}, /Cannot convert object to primitive value/)
}).to.throw('Cannot convert object to primitive value')
})
})
@ -1349,11 +1336,11 @@ describe('chromium feature', () => {
w = new BrowserWindow({ show: false })
w.webContents.once('did-finish-load', async () => {
// History should have current page by now.
assert.strictEqual(w.webContents.length(), 1)
expect(w.webContents.length()).to.equal(1)
w.webContents.executeJavaScript('window.history.pushState({}, "")').then(() => {
// Initial page + pushed state
assert.strictEqual(w.webContents.length(), 2)
expect(w.webContents.length()).to.equal(2)
done()
})
})
@ -1438,32 +1425,32 @@ describe('chromium feature', () => {
let focusChange = expectFocusChange()
w.webContents.sendInputEvent(tabPressEvent)
let focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-1', `should start focused in element-1, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-1', `should start focused in element-1, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
w.webContents.sendInputEvent(tabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-2', `focus should've moved to element-2, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-2', `focus should've moved to element-2, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
w.webContents.sendInputEvent(tabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-wv-element-1', `focus should've moved to the webview's element-1, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-wv-element-1', `focus should've moved to the webview's element-1, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
webviewContents.sendInputEvent(tabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-wv-element-2', `focus should've moved to the webview's element-2, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-wv-element-2', `focus should've moved to the webview's element-2, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
webviewContents.sendInputEvent(tabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-3', `focus should've moved to element-3, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-3', `focus should've moved to element-3, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
w.webContents.sendInputEvent(tabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-1', `focus should've looped back to element-1, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-1', `focus should've looped back to element-1, it's instead in ${focusedElementId}`)
})
})
@ -1478,32 +1465,32 @@ describe('chromium feature', () => {
let focusChange = expectFocusChange()
w.webContents.sendInputEvent(shiftTabPressEvent)
let focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-3', `should start focused in element-3, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-3', `should start focused in element-3, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
w.webContents.sendInputEvent(shiftTabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-wv-element-2', `focus should've moved to the webview's element-2, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-wv-element-2', `focus should've moved to the webview's element-2, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
webviewContents.sendInputEvent(shiftTabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-wv-element-1', `focus should've moved to the webview's element-1, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-wv-element-1', `focus should've moved to the webview's element-1, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
webviewContents.sendInputEvent(shiftTabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-2', `focus should've moved to element-2, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-2', `focus should've moved to element-2, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
w.webContents.sendInputEvent(shiftTabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-1', `focus should've moved to element-1, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-1', `focus should've moved to element-1, it's instead in ${focusedElementId}`)
focusChange = expectFocusChange()
w.webContents.sendInputEvent(shiftTabPressEvent)
focusedElementId = await focusChange
assert.strictEqual(focusedElementId, 'BUTTON-element-3', `focus should've looped back to element-3, it's instead in ${focusedElementId}`)
expect(focusedElementId).to.equal('BUTTON-element-3', `focus should've looped back to element-3, it's instead in ${focusedElementId}`)
})
})
})

View file

@ -1,4 +1,6 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const Module = require('module')
const path = require('path')
const fs = require('fs')
@ -7,6 +9,9 @@ const { BrowserWindow } = remote
const { closeWindow } = require('./window-helpers')
const features = process.electronBinding('features')
const { expect } = chai
chai.use(dirtyChai)
const nativeModulesEnabled = remote.getGlobal('nativeModulesEnabled')
describe('modules support', () => {
@ -27,7 +32,7 @@ describe('modules support', () => {
const echo = path.join(fixtures, 'module', 'echo.js')
const child = require('child_process').fork(echo)
child.on('message', (msg) => {
assert.strictEqual(msg, 'ok')
expect(msg).to.equal('ok')
done()
})
})
@ -39,9 +44,9 @@ describe('modules support', () => {
fs.copyFileSync(execPath, testExecPath)
try {
const fixture = path.join(fixtures, 'module', 'echo-renamed.js')
assert.ok(fs.existsSync(fixture))
expect(fs.existsSync(fixture)).to.be.true()
const child = require('child_process').spawnSync(testExecPath, [fixture])
assert.strictEqual(child.status, 0)
expect(child.status).to.equal(0)
} finally {
fs.unlinkSync(testExecPath)
}
@ -65,7 +70,7 @@ describe('modules support', () => {
const libm = ffi.Library('libm', {
ceil: ['double', ['double']]
})
assert.strictEqual(libm.ceil(1.5), 2)
expect(libm.ceil(1.5)).to.equal(2)
})
})
@ -74,7 +79,7 @@ describe('modules support', () => {
describe('Q.when', () => {
it('emits the fullfil callback', (done) => {
Q(true).then((val) => {
assert.strictEqual(val, true)
expect(val).to.be.true()
done()
})
})
@ -83,10 +88,10 @@ describe('modules support', () => {
describe('coffeescript', () => {
it('can be registered and used to require .coffee files', () => {
assert.doesNotThrow(() => {
expect(() => {
require('coffeescript').register()
})
assert.strictEqual(require('./fixtures/module/test.coffee'), true)
}).to.not.throw()
expect(require('./fixtures/module/test.coffee')).to.be.true()
})
})
})
@ -94,19 +99,19 @@ describe('modules support', () => {
describe('global variables', () => {
describe('process', () => {
it('can be declared in a module', () => {
assert.strictEqual(require('./fixtures/module/declare-process'), 'declared process')
expect(require('./fixtures/module/declare-process')).to.equal('declared process')
})
})
describe('global', () => {
it('can be declared in a module', () => {
assert.strictEqual(require('./fixtures/module/declare-global'), 'declared global')
expect(require('./fixtures/module/declare-global')).to.equal('declared global')
})
})
describe('Buffer', () => {
it('can be declared in a module', () => {
assert.strictEqual(require('./fixtures/module/declare-buffer'), 'declared Buffer')
expect(require('./fixtures/module/declare-buffer')).to.equal('declared Buffer')
})
})
})
@ -115,36 +120,36 @@ describe('modules support', () => {
describe('when the path is inside the resources path', () => {
it('does not include paths outside of the resources path', () => {
let modulePath = process.resourcesPath
assert.deepStrictEqual(Module._nodeModulePaths(modulePath), [
expect(Module._nodeModulePaths(modulePath)).to.deep.equal([
path.join(process.resourcesPath, 'node_modules')
])
modulePath = process.resourcesPath + '-foo'
const nodeModulePaths = Module._nodeModulePaths(modulePath)
assert(nodeModulePaths.includes(path.join(modulePath, 'node_modules')))
assert(nodeModulePaths.includes(path.join(modulePath, '..', 'node_modules')))
expect(nodeModulePaths).to.include(path.join(modulePath, 'node_modules'))
expect(nodeModulePaths).to.include(path.join(modulePath, '..', 'node_modules'))
modulePath = path.join(process.resourcesPath, 'foo')
assert.deepStrictEqual(Module._nodeModulePaths(modulePath), [
expect(Module._nodeModulePaths(modulePath)).to.deep.equal([
path.join(process.resourcesPath, 'foo', 'node_modules'),
path.join(process.resourcesPath, 'node_modules')
])
modulePath = path.join(process.resourcesPath, 'node_modules', 'foo')
assert.deepStrictEqual(Module._nodeModulePaths(modulePath), [
expect(Module._nodeModulePaths(modulePath)).to.deep.equal([
path.join(process.resourcesPath, 'node_modules', 'foo', 'node_modules'),
path.join(process.resourcesPath, 'node_modules')
])
modulePath = path.join(process.resourcesPath, 'node_modules', 'foo', 'bar')
assert.deepStrictEqual(Module._nodeModulePaths(modulePath), [
expect(Module._nodeModulePaths(modulePath)).to.deep.equal([
path.join(process.resourcesPath, 'node_modules', 'foo', 'bar', 'node_modules'),
path.join(process.resourcesPath, 'node_modules', 'foo', 'node_modules'),
path.join(process.resourcesPath, 'node_modules')
])
modulePath = path.join(process.resourcesPath, 'node_modules', 'foo', 'node_modules', 'bar')
assert.deepStrictEqual(Module._nodeModulePaths(modulePath), [
expect(Module._nodeModulePaths(modulePath)).to.deep.equal([
path.join(process.resourcesPath, 'node_modules', 'foo', 'node_modules', 'bar', 'node_modules'),
path.join(process.resourcesPath, 'node_modules', 'foo', 'node_modules'),
path.join(process.resourcesPath, 'node_modules')
@ -155,7 +160,7 @@ describe('modules support', () => {
describe('when the path is outside the resources path', () => {
it('includes paths outside of the resources path', () => {
const modulePath = path.resolve('/foo')
assert.deepStrictEqual(Module._nodeModulePaths(modulePath), [
expect(Module._nodeModulePaths(modulePath)).to.deep.equal([
path.join(modulePath, 'node_modules'),
path.resolve('/node_modules')
])
@ -184,7 +189,7 @@ describe('modules support', () => {
it('searches for module under app directory', async () => {
w.loadURL('about:blank')
const result = await w.webContents.executeJavaScript('typeof require("q").when')
assert.strictEqual(result, 'function')
expect(result).to.equal('function')
})
})
})

View file

@ -1,4 +1,6 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const http = require('http')
const fs = require('fs')
const path = require('path')
@ -9,6 +11,9 @@ const { BrowserWindow } = remote
const { closeWindow } = require('./window-helpers')
const { expect } = chai
chai.use(dirtyChai)
describe('security warnings', () => {
let server
let w = null
@ -66,7 +71,7 @@ describe('security warnings', () => {
}
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('Node.js Integration with Remote Content'), message)
expect(message).to.include('Node.js Integration with Remote Content')
done()
})
@ -84,7 +89,7 @@ describe('security warnings', () => {
}
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('Disabled webSecurity'), message)
expect(message).include('Disabled webSecurity')
done()
})
@ -98,7 +103,7 @@ describe('security warnings', () => {
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('Insecure Content-Security-Policy'), message)
expect(message).to.include('Insecure Content-Security-Policy')
done()
})
@ -115,7 +120,7 @@ describe('security warnings', () => {
}
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('allowRunningInsecureContent'), message)
expect(message).to.include('allowRunningInsecureContent')
done()
})
@ -131,7 +136,7 @@ describe('security warnings', () => {
}
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('experimentalFeatures'), message)
expect(message).to.include('experimentalFeatures')
done()
})
@ -147,7 +152,7 @@ describe('security warnings', () => {
}
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('enableBlinkFeatures'), message)
expect(message).to.include('enableBlinkFeatures')
done()
})
@ -160,7 +165,7 @@ describe('security warnings', () => {
webPreferences
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('allowpopups'), message)
expect(message).to.include('allowpopups')
done()
})
@ -173,7 +178,7 @@ describe('security warnings', () => {
webPreferences
})
w.webContents.once('console-message', (e, level, message) => {
assert(message.includes('Insecure Resources'), message)
expect(message).to.include('Insecure Resources')
done()
})

View file

@ -1,4 +1,3 @@
const assert = require('assert')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const path = require('path')
@ -160,11 +159,11 @@ describe('<webview> tag', function () {
const message = await startLoadingWebViewAndWaitForMessage(webview, {
src: '../fixtures/pages/e.html'
})
assert.strictEqual(message, 'Window script is loaded before preload script')
expect(message).to.equal('Window script is loaded before preload script')
})
it('ignores empty values', () => {
assert.strictEqual(webview.src, '')
expect(webview.src).to.equal('')
for (const emptyValue of ['', null, undefined]) {
webview.src = emptyValue
@ -224,7 +223,7 @@ describe('<webview> tag', function () {
it('disables node integration on child windows when it is disabled on the webview', (done) => {
app.once('browser-window-created', (event, window) => {
assert.strictEqual(window.webContents.getWebPreferences().nodeIntegration, false)
expect(window.webContents.getWebPreferences().nodeIntegration).to.be.false()
done()
})
@ -251,7 +250,7 @@ describe('<webview> tag', function () {
webview.reload()
const { message } = await waitForEvent(webview, 'console-message')
assert.strictEqual(message, 'function')
expect(message).to.equal('function')
})
})
@ -353,8 +352,8 @@ describe('<webview> tag', function () {
webview.send('ping', message)
const { channel, args } = await waitForEvent(webview, 'ipc-message')
assert.strictEqual(channel, 'pong')
assert.deepStrictEqual(args, [message])
expect(channel).to.equal('pong')
expect(args).to.deep.equal([message])
})
it('works without script tag in page', async () => {
@ -388,11 +387,11 @@ describe('<webview> tag', function () {
})
it('ignores empty values', () => {
assert.strictEqual(webview.preload, '')
expect(webview.preload).to.equal('')
for (const emptyValue of ['', null, undefined]) {
webview.preload = emptyValue
assert.strictEqual(webview.preload, '')
expect(webview.preload).to.equal('')
}
})
})
@ -403,7 +402,7 @@ describe('<webview> tag', function () {
const server = http.createServer((req, res) => {
res.end()
server.close()
assert.strictEqual(req.headers.referer, referrer)
expect(req.headers.referer).to.equal(referrer)
done()
}).listen(0, '127.0.0.1', () => {
const port = server.address().port
@ -610,7 +609,7 @@ describe('<webview> tag', function () {
})
const [, data] = await emittedOnce(ipcMain, 'isolated-world')
assert.deepStrictEqual(data, {
expect(data).to.deep.equal({
preloadContext: {
preloadProperty: 'number',
pageProperty: 'undefined',
@ -641,8 +640,8 @@ describe('<webview> tag', function () {
})
const { url, frameName } = await waitForEvent(webview, 'new-window')
assert.strictEqual(url, 'http://host/')
assert.strictEqual(frameName, 'host')
expect(url).to.equal('http://host/')
expect(frameName).to.equal('host')
})
it('emits when link with target is called', async () => {
@ -651,8 +650,8 @@ describe('<webview> tag', function () {
})
const { url, frameName } = await waitForEvent(webview, 'new-window')
assert.strictEqual(url, 'http://host/')
assert.strictEqual(frameName, 'target')
expect(url).to.equal('http://host/')
expect(frameName).to.equal('target')
})
})
@ -664,8 +663,8 @@ describe('<webview> tag', function () {
})
const { channel, args } = await waitForEvent(webview, 'ipc-message')
assert.strictEqual(channel, 'channel')
assert.deepStrictEqual(args, ['arg1', 'arg2'])
expect(channel).to.equal('channel')
expect(args).to.deep.equal(['arg1', 'arg2'])
})
})
@ -676,8 +675,8 @@ describe('<webview> tag', function () {
})
const { title, explicitSet } = await waitForEvent(webview, 'page-title-set')
assert.strictEqual(title, 'test')
assert(explicitSet)
expect(title).to.equal('test')
expect(explicitSet).to.be.true()
})
})
@ -688,12 +687,11 @@ describe('<webview> tag', function () {
})
const { favicons } = await waitForEvent(webview, 'page-favicon-updated')
assert(favicons)
assert.strictEqual(favicons.length, 2)
expect(favicons).to.be.an('array').of.length(2)
if (process.platform === 'win32') {
assert(/^file:\/\/\/[A-Z]:\/favicon.png$/i.test(favicons[0]))
expect(favicons[0]).to.match(/^file:\/\/\/[A-Z]:\/favicon.png$/i)
} else {
assert.strictEqual(favicons[0], 'file:///favicon.png')
expect(favicons[0]).to.equal('file:///favicon.png')
}
})
})
@ -705,7 +703,7 @@ describe('<webview> tag', function () {
})
const { url } = await waitForEvent(webview, 'will-navigate')
assert.strictEqual(url, 'http://host/')
expect(url).to.equal('http://host/')
})
})
@ -722,7 +720,7 @@ describe('<webview> tag', function () {
loadWebView(webview, { src: pageUrl })
const { url } = await waitForEvent(webview, 'did-navigate')
assert.strictEqual(url, pageUrl)
expect(url).to.equal(pageUrl)
})
})
@ -737,7 +735,7 @@ describe('<webview> tag', function () {
})
loadWebView(webview, { src: pageUrl })
const event = await waitForEvent(webview, 'did-navigate-in-page')
assert.strictEqual(event.url, `${pageUrl}#test_content`)
expect(event.url).to.equal(`${pageUrl}#test_content`)
})
it('emits when window.history.replaceState is called', async () => {
@ -745,7 +743,7 @@ describe('<webview> tag', function () {
src: `file://${fixtures}/pages/webview-did-navigate-in-page-with-history.html`
})
const { url } = await waitForEvent(webview, 'did-navigate-in-page')
assert.strictEqual(url, 'http://host/')
expect(url).to.equal('http://host/')
})
it('emits when window.location.hash is changed', async () => {
@ -758,7 +756,7 @@ describe('<webview> tag', function () {
})
loadWebView(webview, { src: pageUrl })
const event = await waitForEvent(webview, 'did-navigate-in-page')
assert.strictEqual(event.url, `${pageUrl}#test`)
expect(event.url).to.equal(`${pageUrl}#test`)
})
})
@ -787,7 +785,7 @@ describe('<webview> tag', function () {
// Its WebContents should be a DevTools.
const devtools = webview2.getWebContents()
assert.ok(devtools.getURL().startsWith('devtools://devtools'))
expect(devtools.getURL().startsWith('devtools://devtools')).to.be.true()
const name = await devtools.executeJavaScript('InspectorFrontendHost.constructor.name')
document.body.removeChild(webview2)
@ -854,7 +852,7 @@ describe('<webview> tag', function () {
webview.reload()
const { channel } = await waitForOnbeforeunload
assert.strictEqual(channel, 'onbeforeunload')
expect(channel).to.equal('onbeforeunload')
})
})
@ -863,15 +861,15 @@ describe('<webview> tag', function () {
let loadCount = 1
const listener = (e) => {
if (loadCount === 1) {
assert.strictEqual(e.channel, 'history')
assert.strictEqual(e.args[0], 1)
assert(!webview.canGoBack())
assert(!webview.canGoForward())
expect(e.channel).to.equal('history')
expect(e.args[0]).to.equal(1)
expect(webview.canGoBack()).to.be.false()
expect(webview.canGoForward()).to.be.false()
} else if (loadCount === 2) {
assert.strictEqual(e.channel, 'history')
assert.strictEqual(e.args[0], 2)
assert(!webview.canGoBack())
assert(webview.canGoForward())
expect(e.channel).to.equal('history')
expect(e.args[0]).to.equal(2)
expect(webview.canGoBack()).to.be.false()
expect(webview.canGoForward()).to.be.true()
webview.removeEventListener('ipc-message', listener)
}
}
@ -880,15 +878,15 @@ describe('<webview> tag', function () {
if (loadCount === 1) {
webview.src = `file://${fixtures}/pages/base-page.html`
} else if (loadCount === 2) {
assert(webview.canGoBack())
assert(!webview.canGoForward())
expect(webview.canGoBack()).to.be.true()
expect(webview.canGoForward()).to.be.false()
webview.goBack()
} else if (loadCount === 3) {
webview.goForward()
} else if (loadCount === 4) {
assert(webview.canGoBack())
assert(!webview.canGoForward())
expect(webview.canGoBack()).to.be.true()
expect(webview.canGoForward()).to.be.false()
webview.removeEventListener('did-finish-load', loadListener)
done()
@ -915,12 +913,12 @@ describe('<webview> tag', function () {
})
const event = await waitForEvent(webview, 'ipc-message')
assert.strictEqual(event.channel, 'history')
assert.strictEqual(event.args[0], 2)
assert(webview.canGoBack())
expect(event.channel).to.equal('history')
expect(event.args[0]).to.equal(2)
expect(webview.canGoBack()).to.be.true()
webview.clearHistory()
assert(!webview.canGoBack())
expect(webview.canGoBack()).to.be.false()
})
})
@ -941,7 +939,7 @@ describe('<webview> tag', function () {
server.listen(0, '127.0.0.1', () => {
const port = server.address().port
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, message)
expect(e.channel).to.equal(message)
done()
})
loadWebView(webview, {
@ -998,7 +996,7 @@ describe('<webview> tag', function () {
const expectedResult = '42'
const result = await webview.executeJavaScript(jsScript)
assert.strictEqual(result, expectedResult)
expect(result).to.equal(expectedResult)
})
})
@ -1018,8 +1016,8 @@ describe('<webview> tag', function () {
})
const { channel, args } = await waitForIpcMessage
assert.strictEqual(channel, 'keyup')
assert.deepStrictEqual(args, ['C', 'KeyC', 67, true, false])
expect(channel).to.equal('keyup')
expect(args).to.deep.equal(['C', 'KeyC', 67, true, false])
})
it('can send mouse event', async () => {
@ -1038,8 +1036,8 @@ describe('<webview> tag', function () {
})
const { channel, args } = await waitForIpcMessage
assert.strictEqual(channel, 'mouseup')
assert.deepStrictEqual(args, [10, 20, false, true])
expect(channel).to.equal('mouseup')
expect(args).to.deep.equal([10, 20, false, true])
})
})
@ -1068,11 +1066,11 @@ describe('<webview> tag', function () {
let requestId = null
const activeMatchOrdinal = []
const listener = (e) => {
assert.strictEqual(e.result.requestId, requestId)
assert.strictEqual(e.result.matches, 3)
expect(e.result.requestId).to.equal(requestId)
expect(e.result.matches).to.equal(3)
activeMatchOrdinal.push(e.result.activeMatchOrdinal)
if (e.result.activeMatchOrdinal === e.result.matches) {
assert.deepStrictEqual(activeMatchOrdinal, [1, 2, 3])
expect(activeMatchOrdinal).to.deep.equal([1, 2, 3])
webview.stopFindInPage('clearSelection')
done()
} else {
@ -1104,7 +1102,7 @@ describe('<webview> tag', function () {
describe('permission-request event', () => {
function setUpRequestHandler (webview, requestedPermission, completed) {
assert.ok(webview.partition)
expect(webview.partition).to.be.a('string').that.is.not.empty()
const listener = function (webContents, permission, callback) {
if (webContents.id === webview.getWebContentsId()) {
@ -1114,7 +1112,7 @@ describe('<webview> tag', function () {
return callback(true)
}
assert.strictEqual(permission, requestedPermission)
expect(permission).to.equal(requestedPermission)
callback(false)
if (completed) completed()
}
@ -1126,8 +1124,8 @@ describe('<webview> tag', function () {
if (isCI) return done()
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'message')
assert.deepStrictEqual(e.args, ['PermissionDeniedError'])
expect(e.channel).to.equal('message')
expect(e.args).to.deep.equal(['PermissionDeniedError'])
done()
})
webview.src = `file://${fixtures}/pages/permissions/media.html`
@ -1139,8 +1137,8 @@ describe('<webview> tag', function () {
it('emits when using navigator.geolocation api', (done) => {
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'message')
assert.deepStrictEqual(e.args, ['User denied Geolocation'])
expect(e.channel).to.equal('message')
expect(e.args).to.deep.equal(['User denied Geolocation'])
done()
})
webview.src = `file://${fixtures}/pages/permissions/geolocation.html`
@ -1152,8 +1150,8 @@ describe('<webview> tag', function () {
it('emits when using navigator.requestMIDIAccess without sysex api', (done) => {
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'message')
assert.deepStrictEqual(e.args, ['SecurityError'])
expect(e.channel).to.equal('message')
expect(e.args).to.deep.equal(['SecurityError'])
done()
})
webview.src = `file://${fixtures}/pages/permissions/midi.html`
@ -1165,8 +1163,8 @@ describe('<webview> tag', function () {
it('emits when using navigator.requestMIDIAccess with sysex api', (done) => {
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'message')
assert.deepStrictEqual(e.args, ['SecurityError'])
expect(e.channel).to.equal('message')
expect(e.args).to.deep.equal(['SecurityError'])
done()
})
webview.src = `file://${fixtures}/pages/permissions/midi-sysex.html`
@ -1185,8 +1183,8 @@ describe('<webview> tag', function () {
it('emits when using Notification.requestPermission', (done) => {
webview.addEventListener('ipc-message', (e) => {
assert.strictEqual(e.channel, 'message')
assert.deepStrictEqual(e.args, ['granted'])
expect(e.channel).to.equal('message')
expect(e.args).to.deep.equal(['granted'])
done()
})
webview.src = `file://${fixtures}/pages/permissions/notification.html`
@ -1194,7 +1192,7 @@ describe('<webview> tag', function () {
webview.setAttribute('nodeintegration', 'on')
session.fromPartition(webview.partition).setPermissionRequestHandler((webContents, permission, callback) => {
if (webContents.id === webview.getWebContentsId()) {
assert.strictEqual(permission, 'notifications')
expect(permission).to.equal('notifications')
setTimeout(() => { callback(true) }, 10)
}
})
@ -1217,7 +1215,7 @@ describe('<webview> tag', function () {
await loadWebView(webview, { src })
const webviewContents = webview.getWebContents()
assert(webviewContents)
expect(webviewContents).to.be.an('object')
expect(webviewContents.getURL()).to.equal(src)
})
})
@ -1252,8 +1250,7 @@ describe('<webview> tag', function () {
await loadWebView(webview, { src })
const data = await webview.printToPDF({})
assert.strictEqual(data instanceof Buffer, true)
assert.notStrictEqual(data.length, 0)
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty()
})
})
@ -1274,16 +1271,16 @@ describe('<webview> tag', function () {
w.show()
const [, visibilityState, hidden] = await pongSignal2
assert(!hidden)
assert.strictEqual(visibilityState, 'visible')
expect(visibilityState).to.equal('visible')
expect(hidden).to.be.false()
})
it('inherits the parent window visibility state and receives visibilitychange events', async () => {
const w = await openTheWindow({ show: false })
w.loadFile(path.join(fixtures, 'pages', 'webview-visibilitychange.html'))
const [, visibilityState, hidden] = await emittedOnce(ipcMain, 'pong')
assert.strictEqual(visibilityState, 'hidden')
assert.strictEqual(hidden, true)
expect(visibilityState).to.equal('hidden')
expect(hidden).to.be.true()
// We have to start waiting for the event
// before we ask the webContents to resize.
@ -1291,8 +1288,8 @@ describe('<webview> tag', function () {
w.webContents.emit('-window-visibility-change', 'visible')
return getResponse.then(([, visibilityState, hidden]) => {
assert.strictEqual(visibilityState, 'visible')
assert.strictEqual(hidden, false)
expect(visibilityState).to.equal('visible')
expect(hidden).to.be.false()
})
})
})
@ -1343,7 +1340,7 @@ describe('<webview> tag', function () {
src: `file://${fixtures}/pages/a.html`
})
assert.strictEqual(message, 'undefined')
expect(message).to.equal('undefined')
})
})

View file

@ -2,7 +2,7 @@ var app = require('electron').app
var fs = require('fs')
var request = require('request')
var TARGET_URL = 'https://atom.io/download/electron/index.json'
var TARGET_URL = 'https://electronjs.org/headers/index.json'
function getDate () {
var today = new Date()

1509
yarn.lock

File diff suppressed because it is too large Load diff