Giter Club home page Giter Club logo

ember-window-mock's Introduction

ember-window-mock

CI Ember Observer Score npm version

This Ember CLI addon provides the window global as an ES6 module import that you can use in any component or controller where you need window. But some of its properties and functions are prohibitive to be used in tests as they will break the test run:

  • you cannot set window.location.href to trigger a redirect, as that will leave your test page
  • alert, confirm and prompt are blocking calls, and cannot be closed without user interaction, so they will just suspend your test run

So when running tests this import will be replaced with one that mocks these critical parts.

Compatibility

  • Ember.js v4.4 or above
  • Ember CLI v4.4 or above
  • Node.js v16 or above

Installation

ember install ember-window-mock

Usage

How to use it in your app

Let's say you want to redirect to an external URL. A simple controller could look like this:

import Controller from "@ember/controller";
import { action } from "@ember/object";

export default class IndexController extends Controller {
  @action
  redirect(url) {
    window.location.href = url;
  }
}

With this addon, you can just import window instead of using the global:

import Controller from "@ember/controller";
import { action } from "@ember/object";
import window from "ember-window-mock";

export default class IndexController extends Controller {
  @action
  redirect(url) {
    window.location.href = url;
  }
}

Everything else works as you would expect, since the import is exactly the same as the global, when not running tests.

The window mock

When running in the test environment, the import will be replaced with a mock. It is a proxy to window, so all of the non-critical properties and functions just use the normal window global. But the critical parts are replaced suitable for tests:

  • window.location is mocked with an object with the same API (members like .href or .host), but setting location.href will just do nothing. Still reading from location.href will return the value that was previously set, so you can run assertions against that value to check if you app tried to redirect to the expected URL.
  • window.localStorage is also mocked with an object with the same API (getItem, setItem, removeItem, clear, key, and length). Storage is not persistent and does not affect your browser's localStorage object.
  • window.sessionStorage is mocked similar to window.localStorage.
  • alert, confirm and prompt are replaced by simple noop functions (they do nothing). You can use a mocking library like Sinon.js to replace them with spies or stubs to assert that they have been called or to return some predefined value (e.g. true for confirm).

Moreover it allows you to set any (nested) properties, even if they are defined as read only. This way you can pretend different environments in your tests. For example you can fake different devices by changing

  • window.navigator.userAgent when you do user agent detection in your app.
  • window.screen.width to test responsive layouts when your components render differently based on it.

See below for some examples.

Important:

  • The window mock works by using an ES6 Proxy, so your development environment and tests need to run in a browser like Chrome that supports Proxy natively (as it cannot be transpiled by Babel)
  • Note that this will only work when you use these function through the import, and not by using the global directly.

Resetting the state in tests

It is possible to leak some state on the window mock between tests. For example when your app sets location.href in a test like this:

window.location.href = "http://www.example.com";

For the following test window.location.href will still be 'http://www.example.com', but instead it should have a fresh instance of the window mock. Therefore this addon exports a setupWindowMock function to kill all changed state on window:

import { setupWindowMock } from 'ember-window-mock/test-support';

module('SidebarController', function(hooks) {
  setupWindowMock(hooks);

  test(...);
});

Test examples

Mocking window.location

Given a controller like the one above, that redirects to some URL when a button is clicked, an application test could like this:

import { module, test } from "qunit";
import { click, visit } from "@ember/test-helpers";
import { setupApplicationTest } from "ember-qunit";
import window from "ember-window-mock";
import { setupWindowMock } from "ember-window-mock/test-support";

module("Acceptance | redirect", function (hooks) {
  setupApplicationTest(hooks);
  setupWindowMock(hooks);

  test("it redirects when clicking the button", async function (assert) {
    await visit("/");
    await click("button");

    assert.equal(window.location.href, "http://www.example.com");
  });
});

Mocking confirm()

Here is an example that uses ember-sinon-qunit to replace confirm, so you can easily check if it has been called, and to return some defined value:

import { module, test } from "qunit";
import { click, visit } from "@ember/test-helpers";
import { setupApplicationTest } from "ember-qunit";
import window from "ember-window-mock";
import { setupWindowMock } from "ember-window-mock/test-support";
import sinon from "sinon";

module("Acceptance | redirect", function (hooks) {
  setupApplicationTest(hooks);
  setupWindowMock(hooks);

  test("it deletes an item", async function (assert) {
    let stub = sinon.stub(window, "confirm");
    stub.returns(true);

    await visit("/");
    await click("[data-test-delete]");

    assert.ok(stub.calledOnce);
    assert.ok(stub.calledWith("Are you sure?"));
  });
});

Mocking open()

Here is an example that assigns a new function to replace open. You can check if the function has been called as well as the value of its parameters.

import { module, test } from "qunit";
import { click, visit } from "@ember/test-helpers";
import { setupApplicationTest } from "ember-qunit";
import window from "ember-window-mock";
import { setupWindowMock } from "ember-window-mock/test-support";

module("Acceptance | new window", function (hooks) {
  setupApplicationTest(hooks);
  setupWindowMock(hooks);

  test("it opens a new window when clicking the button", async function (assert) {
    await visit("/");
    window.open = (urlToOpen) => {
      assert.equal(urlToOpen, "http://www.example.com/some-file.jpg");
    };
    await click("button");
  });
});

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.

ember-window-mock's People

Contributors

dependabot-preview[bot] avatar simonihmig avatar renovate[bot] avatar renovate-bot avatar dependabot[bot] avatar greenkeeper[bot] avatar robbiethewagner avatar alisdair avatar stfnio avatar makepanic avatar buschtoens avatar alexlafroscia avatar hakilebara avatar gaurav0 avatar elwayman02 avatar ember-tomster avatar topsycm avatar

Stargazers

Tuan Duc Tran avatar Ron avatar Bert De Block avatar Angela Pan avatar Justin Workman avatar Craig Teegarden avatar Paulo Fernandes avatar Slimane Amiar avatar Sean Juarez avatar Fabrício Tavares avatar Sean Goresht avatar Eyüp Atiş avatar Cyrille David avatar davidphilip avatar Justin Drew avatar Adrian avatar Tobias Bieniek avatar Rafael Santos avatar Dawid Pośliński avatar (Alex/Alexey) Aleksei (Stree’Jacque) Strizhak avatar Gabriel Cousin avatar Jarek Radosz avatar Ian irving avatar Quinten Powell avatar Ben Kiefer avatar Nathan Selikoff avatar Kevin Fleischman avatar Sylwia avatar Matt Gardner avatar  avatar Alvin Vogelzang avatar Maxim Malov avatar Mark Oleson avatar Pablo Graviel Seo avatar Kevin Fagan avatar Jacek Bandura avatar Matt McManus avatar Scott Newcomer avatar Julian Tescher avatar  avatar Martin Malinda avatar Will Viles avatar  avatar Greg Larrenaga avatar Jacky Alciné avatar  avatar Jason Mitchell avatar Kelly Selden avatar Ryunosuke Sato avatar Deniss Alimovs avatar Esteban avatar Michael Swanson avatar Max Fierke avatar David Tang avatar Denys Slipetskyy avatar Dave Laird avatar Ahmad Musaffa avatar Yusuf Karagol avatar Gabor Babicz avatar Ilya Radchenko avatar Alex Middeleer avatar  avatar

Watchers

James Cloos avatar  avatar  avatar

ember-window-mock's Issues

optional window service in addon

We have an addon with an optional dependency of ember-window-mock. The service injection is:

  window: computed(function() {
    return getOwner(this).lookup('service:window');
  }),

How would we do this in 0.3+? Is it entirely up to the app to inject a mocked window?

Is there a way to extend the service?

I would like to do some custom scrollTo stuff on the service:

import Service from 'ember-window-mock/somewhere';

export default Service.extend({
  scrollTo() {
    // custom stuff
  }
});

Is this possible with the way you are using factories?

Support for localStorage

This addon is really useful, thanks for making it! 🎉

It might be helpful to have a mock for localStorage, similar to the location one: implementing the normal API, against an ephemeral store. This would make it easier for me to avoid state leaking across tests.

Would that make sense to you? Wanted to check before working on a PR.

Support `window.history`

Hi,
Either I've miss something or not, but the README doesn't make any mention of window.history

I was trying to test my back button that basically does window.history.back() but my test was still returning to the previous page 😅

In the controller that contain the goBack function I've added
import window from 'ember-window-mock';

and in the test I've added both
import { setupWindowMock } from 'ember-window-mock';
and
setupWindowMock(hooks);

Is this out of scope to support things like that with history or should I do it another way ?

Thanks for your help

Impossible to trigger jQuery events on imported window object after v0.6.0

jQuery .on listeners are not firing when you .trigger an event in dev environment on imported window object from ember-window-mock.

Steps to reproduce

  1. Import window from "ember-window-mock"
  2. Add $(window).on("some-event", ...) event listener
  3. Open browser console and $(window).trigger("some-event"))

Last working ember-window-mock version: 0.6.0
jQuery version: 3.5.1

Figure out a way to not need to call mockWindow in each test

Discussed this some in slack with @simonihmig but we didn't come up with any definitive solution. The main problem with calling mockWindow in each test, for me, is if I use it in an addon, then someone consumes my addon, they may not know about this requirement, and it could break their tests and be hard for them to figure out how to fix.

Broken after 0.1.2

Hey, I have a test that started failing after 0.1.2, I verified that it breaks when I upgrade so for now I'm just reporting and pinning our version to that:

It seems that the window.location.href ends up backwards as ://{pathname}{host}

sinonTest('loginRedirectUrlWithReturn forms proper retUrl', function(assert) {
    assert.expect(5);

    // Mock the window data using ember-window-mock service.
    // NOTE: FAILS AFTER 0.1.2 with result window.location.href == ':///seattle/https://gym.com`
    lookupWindow(this).location.href = 'https://gym.com';
    lookupWindow(this).location.pathname = '/seattle/';

    const comp = this.subject({ loginRedirectUrl: 'https://foo.com' });

    const classUrl = '#/week/2345';
    const redirectStub = this.spy(get(comp, 'redirect'), 'getWithReturnRedirect');
    const routerStub = this.stub(get(comp, 'router'), 'urlFor').returns(classUrl);
    const loginRedirectUrlWithReturn = get(comp, 'loginRedirectUrlWithReturn');

    assert.equal(redirectStub.calledOnce, true);
    assert.equal((redirectStub.args[0][1].indexOf(classUrl) > -1), true);
    assert.equal(routerStub.calledOnce, true);

    const { origin, searchParams } = new URL(loginRedirectUrlWithReturn);

    assert.equal(origin, 'https://foo.com');
    assert.equal(searchParams.get('mtredirect'), `https://gym.com/seattle/${classUrl}`);
});

related code

    loginRedirectUrlWithReturn: computed('loginRedirectUrl', function() {
        const loginRedirectUrl = get(this, 'loginRedirectUrl');
        const redirect = get(this, 'redirect');
        const path = get(this, 'router').urlFor('week.class', get(this, 'classSession.id'));
        const { host, pathname, protocol } = get(this, 'window').location;
        const returnUrl = `${protocol}//${host}${pathname}${path}`;

        return redirect.getWithReturnRedirect(loginRedirectUrl, returnUrl);

`window.document` cannot be mocked / replaced

I tried something like this:

  hooks.beforeEach(function() {
    class DocumentMock extends EventTarget {
      // ... some custom `window.document` mock
    }

    window.document = new DocumentMock();
  });

But this throws the following error:

TypeError: 'set' on proxy: trap returned truish for property 'document'
  which exists in the proxy target as a non-configurable and non-writable
  accessor property without a setter

The reason being

Take a look at the following, section 9.5.9 of the ECMA spec:

http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver

A riveting read I'm sure you'll agree.

I believe the two keys lines are:

Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P, V, Receiver»)).

and the equally esoteric:

If targetDesc is not undefined, then
a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is false and targetDesc.[[Writable]] is false, then

i. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError exception.

There is this relevant comment in the NOTE section:

Cannot change the value of a property to be different from the value of the corresponding target object property if the corresponding target object property is a non-writable, non-configurable own data property.

StackOverflow

With the current setup, it is not possible to completely mock properties like document.

Can we maybe add a method / export a function to directly set properties on the holder? This way we could do something like:

import window, { mock } from 'ember-window-mock';

module('foo', function(hooks) {
  hooks.beforeEach(function() {
    class DocumentMock extends EventTarget {
      // ...
    }

    mock('document', new DocumentMock());
  });
});

_emberWindowMock.default.location.href is not a function

Hi, I'm getting this error:

 _emberWindowMock.default.location.href is not a function. (In '_emberWindowMock.default.location.href(redirectUrl)', '_emberWindowMock.default.location.href

Ember 3.2, no fastboot.

window.location.replace() works fine...

delete window.prop regression?

My tests started failing that involved delete window._satellite;. It appears it no longer goes through the set logic, so all gets still have the targets property intact.

Tries to create new Proxy of null

Hi,
I've upgrade from 0.3.0 to 0.5.0 and saw failing tests.
Investigating further, it looks like window-mock tries to create a Proxy of null.

I was trying to use window-mock on window.onbeforeunload. This is initially null if nothing is registered.

20181005-141016

This causes the code to create a new Proxy(null, ...) which isn't valid:

20181005-141031

Is this an issue in how I am using window-mock or an actual bug?

An in-range update of eslint-plugin-ember is breaking the build 🚨

The devDependency eslint-plugin-ember was updated from 6.8.2 to 6.9.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint-plugin-ember is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v6.9.0

🚀 Enhancement

  • #458 Add new rule require-computed-property-dependencies (@bmish)

🐛 Bug Fix

  • #463 Fix false positives for import statements with use-ember-data-rfc-395-imports rule (@fusion2004)

🏠 Internal

  • #465 Add tests that rules are setup correctly (not missing tests, docs, exports, etc) (@bmish)
  • #466 Fix eslint 6 rule test parser error (@bmish)

Committers: 2

Commits

The new version differs by 11 commits.

  • 344ef33 v6.9.0
  • 85a0c5f Update CHANGELOG
  • ef7d2e0 Merge pull request #458 from bmish/require-computed-property-dependencies
  • 2b7521d build(deps): [security] bump stringstream from 0.0.5 to 0.0.6 (#467)
  • 6b2b668 Merge pull request #465 from bmish/test-rule-setup
  • 69e7a4a Merge pull request #466 from bmish/eslint-6-parser-test-error
  • d0bacc0 feat: add new rule require-computed-property-dependencies
  • 5ca8fc3 test: fix eslint 6 rule test parser error
  • 0a6963c test: add tests that rules are setup correctly (not missing tests, docs, exports, etc)
  • 1da0fb4 Merge pull request #463 from fusion2004/fix-ember-data-rfc395-rule
  • 41de083 Change use-ember-data-rfc-395-imports to not match against imports from libraries whose names start with 'ember-data'

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Issue mocking Notification

Hi,

I'm seeing an issue when trying to use window-mock with Notification.requestPermission.

The issue is that typeof Notification is function where window-mock returns a bound version of it.

20181120-131139

But somehow creating a bound instance of Notification erases its "static" methods.

20181120-131119

I think we could fix this by adding "Notification" to the list of proxyFactory users. If that's ok, I can open a PR for it.

edit: nvm. I think that doesn't really work

An in-range update of ember-resolver is breaking the build 🚨

The devDependency ember-resolver was updated from 5.1.3 to 5.2.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

ember-resolver is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for Release 5.2.0

v5.2.0 (2019-08-01)

🐛 Bug Fix

📝 Documentation

Committers: 3

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Illegal invocation of dispatchEvent in test

I have a call to window.dispatchEvent which gives an Illegal invocation error when run in tests. It works otherwise. The call is made from a bound function as follows:

  window: service(),

  init() {
    this._super(...arguments);
    let broadcast = bind(this, this.broadcast);
    get(this, 'someService').on('someEvent', broadcast);
  },

  broadcast() {
    let window = get(this, 'window');
    window.dispatchEvent(new Event('event-name'));
  },

Is there something else I need to be doing to maintain the correct context?

Automatically run mockWindow(this) in beforeEach

Hey so I added this to a sizable codebase and running ember test about 30+ tests fail across multiple files because of unknown injection. It seems like if this package automatically ran mockWindow(this) in beforeEach._super() it would make life a lot easier :D

Export function to setup window mock reset in new ember-qunit tests

Thanks for maintaining this addon.

The recent version of ember-qunit applies functions on the qunit hooks to setup ember specific stuff:

import { setupTest } from 'ember-qunit';

module('SidebarController', function(hooks) {
  setupTest(hooks);
  // ...
});

ember-window-mock could export a function like setupWindowMockTest(hooks) which adds calls to reset in the hooks beforeEach, afterEach functions.

e.g. something like:

import {setupWindowMockTest} from 'ember-window-mock';

module('SidebarController', function(hooks) {
  setupWindowMockTest(hooks);
  // ...
});

This is mostly cosmetic but reduces the work a user has to do to use window mock in testing.
If this is an addition to window mock that you want to have, I can open a PR.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Warning

These dependencies are deprecated:

Datasource Name Replacement PR?
npm release-it-lerna-changelog Unavailable

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Update babel monorepo (patch) (@babel/eslint-parser, @babel/plugin-proposal-decorators)
  • Update dependency @embroider/macros to v1.13.5
  • Update dependency ember-auto-import to v2.7.4
  • Update dependency ember-cli to v4.12.3
  • Update dependency ember-page-title to v8.2.3
  • Update dependency ember-source to v4.12.4
  • Update dependency qunit to v2.20.1
  • Update babel monorepo to v7.24.7 (minor) (@babel/eslint-parser, @babel/plugin-proposal-decorators)
  • Update dependency @ember/optional-features to v2.1.0
  • Update dependency @ember/test-helpers to v3.3.0
  • Update dependency @embroider/macros to v1.16.5
  • Update dependency ember-qunit to v8.1.0
  • Update dependency eslint to v8.57.0
  • Update dependency qunit to v2.21.0
  • Update dependency qunit-dom to v3.2.0
  • Update dependency webpack to v5.92.1
  • Update dependency @embroider/test-setup to v4
  • Update dependency ember-resolver to v12
  • Update dependency ember-template-lint to v6
  • Update dependency eslint to v9
  • Update dependency eslint-plugin-n to v17
  • Update dependency sinon to v18
  • Update dependency stylelint-config-standard to v36
  • Update dependency stylelint-prettier to v5
  • Lock file maintenance
  • 🔐 Create all rate-limited PRs at once 🔐

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v3
  • actions/setup-node v4
  • actions/checkout v3
  • actions/setup-node v4
  • actions/checkout v3
  • actions/setup-node v4
npm
package.json
  • ember-cli-babel ^7.26.11
  • ember-cli-htmlbars ^6.2.0
  • @babel/eslint-parser 7.23.3
  • @babel/plugin-proposal-decorators 7.23.7
  • @ember/optional-features 2.0.0
  • @ember/string 3.1.1
  • @ember/test-helpers 3.2.1
  • @embroider/macros 1.13.4
  • @embroider/test-setup 3.0.3
  • @glimmer/component 1.1.2
  • @glimmer/tracking 1.1.2
  • broccoli-asset-rev 3.0.0
  • concurrently 8.2.2
  • ember-auto-import 2.7.2
  • ember-cli 4.12.2
  • ember-cli-dependency-checker 3.3.2
  • ember-cli-inject-live-reload 2.1.0
  • ember-cli-sri 2.1.1
  • ember-cli-terser 4.0.2
  • ember-load-initializers 2.1.2
  • ember-page-title 8.2.0
  • ember-qunit 8.0.2
  • ember-resolver 11.0.1
  • ember-sinon-qunit 7.4.0
  • ember-source 4.12.3
  • ember-source-channel-url 3.0.0
  • ember-template-lint 5.13.0
  • ember-try 3.0.0
  • eslint 8.56.0
  • eslint-config-prettier 9.1.0
  • eslint-plugin-ember 11.12.0
  • eslint-plugin-n 16.6.2
  • eslint-plugin-prettier 4.2.1
  • eslint-plugin-qunit 7.3.4
  • jquery 3.7.1
  • loader.js 4.7.0
  • prettier 2.8.8
  • qunit 2.20.0
  • qunit-dom 3.0.0
  • release-it 15.11.0
  • release-it-lerna-changelog 5.0.0
  • sinon 17.0.1
  • stylelint 15.11.0
  • stylelint-config-standard 34.0.0
  • stylelint-prettier 3.0.0
  • webpack 5.89.0
  • ember-source ^4.0.0
  • node 16.* || >= 18

  • Check this box to trigger a request for Renovate to run again on this repository

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.

Since we did not receive a CI status on the greenkeeper/initial branch, we assume that you still need to configure it.

If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/.

We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

Once you have installed CI on this repository, you’ll need to re-trigger Greenkeeper’s initial Pull Request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper integration’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Thank you

Just started using this at work. It's great!

starting in v0.7.0, setting window.onerror results in TypeError: Illegal invocation

Ember version 3.12.0 / cli 3.12.1

I have a logging service trying to set window.onerror in the init block to catch errors that bubble all the way up to the browser window and log them.

The following code was working until v0.7.0 of ember-window-mock:
window.onerror = (...nestedArgs) => this.onWindowError(...nestedArgs);

I can get it to work just fine (as above) in v0.6.0 and lower. I've tried various bindings and whatnot to try to resolve the error, but to no avail. All of the following also cause the same issue.

window.onerror = this.onWindowError;
window.onerror = this.onWindowError.bind(window);
window.onerror = this.OnWindowError.bind(this);
window.onerror = function (...args) { debugger; };
window.onerror = function (msg, url, line, column, error){
  this.onWindowError(msg, url, line, column, error);
};
window.onerror = (msg, url, line, column, error) => this.onWindowError(msg, url, line, column, error);

I'm not sure what change caused the issue... looking at the commits between 0.6.0 and 0.7.0 mostly just were various dependency bumps and embroider support.

IE 11 support

I know, that ember-window-mock can't fully work in IE11, because of the missing Proxy support. However, it would be nice, if it wouldn't crash the full test suite. 😅

Since new URL is not available in IE11, this line crashes everything:

https://github.com/kaliber5/ember-window-mock/blob/ada959b92f104c875066140be3c3ca7f34110f7d/addon-test-support/-private/mock/location.js#L25

There's potentially more, but I haven't yet debugged it. Would you accept a PR that make ember-window-mock play a bit nicer with IE11?

Can no longer stub window methods using sinon

Starting from Sinon version 11.1.0, it is no longer possible to stub properties and methods on window, as suggested in the readme:

let stub = sinon.stub(window, 'confirm');
stub.returns(true);

This will throw an error:
CleanShot 2022-06-08 at 14 42 46

TypeError: Cannot read properties of undefined (reading 'get')
    at getAccessor (webpack://__ember_auto_import__/./node_modules/sinon/lib/sinon/util/core/wrap-method.js?:1:1061)
    at extendObjectWithWrappedMethods (webpack://__ember_auto_import__/./node_modules/sinon/lib/sinon/util/core/wrap-method.js?:8:208)
    at wrapMethod (webpack://__ember_auto_import__/./node_modules/sinon/lib/sinon/util/core/wrap-method.js?:8:87)
    at Function.stub (webpack://__ember_auto_import__/./node_modules/sinon/lib/sinon/stub.js?:3:1569)
    at Sandbox.stub (webpack://__ember_auto_import__/./node_modules/sinon/lib/sinon/sandbox.js?:8:720)
    at Object.<anonymous> (http://localhost:13123/assets/tests.js:41707:22)

I tracked it down to this PR in Sinon itself sinonjs/sinon#2378, which shipped in version 11.1.0. More specifically, it seems that Sinon may have a bug when trying to mock/stub properties on Proxy objects.

This may be related to issues like #99

I understand that this may be for Sinon to fix, but it would be worth updating the readme to account for this. Maybe include a built-in option to easily mock and restore window methods/properties?

Fails to use with replace

I imported window as suggested in README and have the following beforeModel hook in index.js route:

import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import config from '../config/environment';
import isFastBoot from 'ember-simple-auth/utils/is-fastboot';
import UnauthenticatedRouteMixin from 'ember-simple-auth/mixins/unauthenticated-route-mixin';
import window from 'ember-window-mock';

export default Route.extend(UnauthenticatedRouteMixin, {
  session:      service('session'),
   _isFastBoot: isFastBoot(),

  beforeModel: function() {
   this._super(...arguments);
    if (this.get('session.isAuthenticated')) {
      this.transitionTo('dashboard');
    } else {
      if (!this.get('_isFastBoot')) {
        let oauthUrl = config.oauthUrl;
        let clientId = config.clientID;
        let redirectURI = `${window.location.origin}/callback`;
        let responseType = `token`;
        let scope = `profile%20openid`;
        window.location.replace(oauthUrl
                              + `?client_id=${clientId}`
                              + `&redirect_uri=${redirectURI}`
                              + `&response_type=${responseType}`
                              + `&scope=${scope}`
        );
      }
    }
  }
});

Then when running the simple acceptance test:

import { module, test } from 'qunit';
import { visit, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { authenticateSession } from 'ember-simple-auth/test-support';
import setupMirageTest from 'ember-cli-mirage/test-support/setup-mirage';
import { setupWindowMock } from 'ember-window-mock';

module('Acceptance | Dashboard', function(hooks) {
  setupApplicationTest(hooks);
  setupMirageTest(hooks);
 setupWindowMock(hooks);

  test('Authenticated users can visit /dashboard', async function(assert) {
    let shop = this.server.create('shop');
    this.server.create('user', { shop });
    
    await authenticateSession({
      access_token: 'abcdDEF',
      token_type: 'Bearer'
    });
    await visit('/dashboard');

    assert.equal(currentURL(), '/dashboard', 'user is on dashboard page');
  });
});

It fails as follows
screenshot 2019-02-08 at 16 27 10

Why so and what am I missing?
The actual behavior outside tests is as follows:

  • if a User is not authenticated, he is redirected to the corporate gateway login page
  • after entering his username and password, he is redirected back to the app as https://myapp/callback#access_token=2YotnFZFEjr1zCsicMWpAA&type=Bearer&expire_in=3600&state=myAppRandomState and ESA (ember-simple-auth) grabs the token.

What is strange, if I change:

assert.equal(currentURL(), '/dashboard', 'user is on dashboard page');

for

assert.equal(window.location.href, '/dashboard', 'user is on dashboard page');

the test fails and displays clearly the difference in the compared URL:


Expected: | "/dashboard"
-- | --

Result: t"https://corporate-gateway-url/as/authorization.oauth2?client_id=decastore&redirect_uri=http://localhost:7357/callback&response_type=token&scope=profile%20openid"

Diff: "https://corporate-gateway-url/ashboar/authorization.oauth2?client_id=decastore&redirect_uri=http://localhost:7357/callback&response_type=token&scope=profile%20openid"

Thank you!

"property 'window' is a read-only and non-configurable data property " error in first test ran

Sorry, filing an issue is not the best for this, but unsure where else to post. I tried adding this in a repository that has some acceptances, integration/rendering tests, and unit tests. My first (acceptance) test fails with this error.

‣
TypeError: 'get' on proxy: property 'window' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<Window>' but got '[object Object]')
    at isWindow (http://localhost:7357/assets/vendor.js:12508:37)
    at isArrayLike (http://localhost:7357/assets/vendor.js:12915:28)
    at Function.makeArray (http://localhost:7357/assets/vendor.js:12804:9)
    at new jQuery.fn.init (http://localhost:7357/assets/vendor.js:15430:17)
    at jQuery (http://localhost:7357/assets/vendor.js:12562:10)
    at Class.init (http://localhost:7357/assets/webapp.js:64113:7)
    at Class.superWrapper [as init] (http://localhost:7357/assets/vendor.js:65580:28)
    at Class.CoreObject (http://localhost:7357/assets/vendor.js:63012:27)
    at Class.EmberObject (http://localhost:7357/assets/vendor.js:63395:75)
    at Class (http://localhost:7357/assets/vendor.js:63074:72)

how can i resolve this? thx!

I'm open to making a PR to add documention to the README with the resolution of this, if applicable.


ember 3.4.7
"ember-mocha": "^0.14.0"


For setting up my acceptance tests, I tried variations of

import { setupWindowMock, reset as resetWindow } from 'ember-window-mock';

export const runBeforeHooks = () => {
  // see https://github.com/kaliber5/ember-window-mock#resetting-the-state-in-tests
  resetWindow();
  // setupWindowMock();
  setupRouter();
};

export const setupApplicationTest = function (testContext) {
  const hooks = mochaSetupApplicationTest();

  setupWindowMock(hooks);
  hooks.beforeEach(runBeforeHooks);

  return hooks;
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.