Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way to set window.location and window.parent.location to different values? #348

Closed
nelstrom opened this issue Aug 4, 2022 · 3 comments

Comments

@nelstrom
Copy link
Contributor

nelstrom commented Aug 4, 2022

We have a helper called is-running-in-iframe. It compares the value of window.location.href and window.parent.location.href. If these values are different, then (for our purposes) that means our Ember app is running inside an iframe.

In our implementation of the helper, we use @service('browser/window') to help with testing. Our test looks like this (simplified here for clarity):

import { render } from '@ember/test-helpers';
import { setupBrowserFakes } from 'ember-browser-services/test-support';
import { hbs } from 'ember-cli-htmlbars';
import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';

module('Integration | Helper | is-running-in-iframe', function (hooks) {
  setupRenderingTest(hooks);
  setupBrowserFakes(hooks, { window: true });

  test('it returns TRUE when the app is running in an IFrame', async function (assert) {
    let browserWindowMock = this.owner.lookup('service:browser/window');
    browserWindowMock.location.href = 'inner';
    browserWindowMock.parent.location.href = 'outer';

    await render(hbs`{{if (is-running-in-iframe) "TRUE" "FALSE"}}`);

    assert.dom(this.element).hasText('TRUE');
  });
});

This test worked with version 1.1.6 of ember-browser-services. After upgrading to version 2.1.0, this test started to fail.

After investigating, I've tracked down the problem to this line of code:

(If I comment out that line, then our test passes.)

I understand that ember-browser-services is intentionally keeping the value of window.location and window.parent.location in sync. I found the relevant tests. But here we have a case where we want to allow those values to diverge.

Do you have any thoughts about how to support this?

@nelstrom
Copy link
Contributor Author

nelstrom commented Aug 4, 2022

In src/test-support/index.ts I noticed this hint: "default, can still be overwritten".

I tried using the maybeMake() function directly (instead of using setupBrowserFakes()):

import { render } from '@ember/test-helpers';
import { maybeMake } from 'ember-browser-services/test-support';
import { hbs } from 'ember-cli-htmlbars';
import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';

module('Integration | Helper | is-running-in-iframe', function (hooks) {
  setupRenderingTest(hooks);
  hooks.beforeEach(function () {
    let service = maybeMake(true, window);
    this.owner.register('service:browser/window', service);
  });

  test('it returns TRUE when the app is running in an IFrame', async function (assert) {
    let browserWindowMock = this.owner.lookup('service:browser/window');
    browserWindowMock.location.href = 'inner';
    browserWindowMock.parent.location.href = 'outer';

    await render(hbs`{{if (is-running-in-iframe) "TRUE" "FALSE"}}`);

    assert.dom(this.element).hasText('TRUE');
  });
});

Am I on the right lines here?


I also saw this: simonihmig/ember-window-mock#175, which seems to be related

I'd like to set the window.parent.location.href, but not window.location.href

@NullVoxPopuli
Copy link
Contributor

thanks for the report!

yeah, you're on the right track! -- and what you have is a valid way to test this stuff -- though, it would def be great to figure out a way make this more ergonomic (but what you haven't isn't bad or anything, it's just manual)

I copied the gist of your report here: #349
(using setupBrowserFakes still, because.. it should be possible?)

Do you have any thoughts about how to support this?

the only thing I can think of is maybe opting out of that if key === parent line that you identified. like, maybe if setBrowserFakes provides a parent, we skip that part of patchWindow?
This is tricky because we need to recursively pass the windowOptions / mock down through the patchWindow proxy to see when to opt out at the right time. 🤔
I'm a little uncertain on exact execution atm, but if you have an idea, a PR would be greatly welcome <3

@nelstrom
Copy link
Contributor Author

nelstrom commented Aug 8, 2022

@NullVoxPopuli thanks for your response.

I realised that I could take a different approach here. Our is-running-in-iframe-helper calls a pure JS function called isRunningInIframe(_window). Previously, we had an integration test (a.k.a. rendering test) for this, which relied on ember-browser-services to mock the window object. I've replaced that test with a unit test for the isRunningInIframe() function, which I can call with a simple POJO:

{
  location: 'inner',
  parent: { location: 'outer' },
}

This works fine for our situation. Happy to close this issue now.

@nelstrom nelstrom closed this as completed Aug 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants