admin管理员组

文章数量:1277886

I have a small webapp that opens a link in a new window. The document in the new window then interacts with the original webapp through the DOM.

The webapp itself is written in Angular, but the link is plain HTML (not even coming from an Angular template). The target document is not Angular, just plain HTML/CSS/JS:

  <a target="_blank" rel="opener" href="/assets/probes/xss.html">Click here!</a>

Tests are set up according to Angular's component testing guide. Here's a snippet of the setup code:

  beforeEach(async () => {
    TestBed.configureTestingModule(xssDemoConfig);
    await TestBedpileComponents();
    fixture = TestBed.createComponent(XssDemoComponent);
    fixture.detectChanges();

    // ...
  });

This setup works like a charm for hundreds of other tests. The new test code is simple:

  el.querySelector('a').click();

I've confirmed in the browser debug console that the selector returns the correct <a> element. (And I have other working tests that trigger click events on similar links — only difference is that those links have javascript: URLs and do not open a new window or even trigger navigation.)

Everything works like a charm when testing manually in a browser. However, when my new tests try to click the link, nothing at all happens. No new window, but no error or log message either. My spec just runs into a timeout. (I've tried more generous timeouts, but this hasn't fixed it.)

So, finally my questions:

  • Why is this happening?
  • Does the Angular TestBed, or Jasmine, or Karma have some hidden feature that intercepts such clicks?
  • If so, which of them is at fault here?
  • Is there any way that I could bypass this undesired behavior?
  • Is such testing feasible with Karma/Jasmine at all?
  • If not, which other tools/frameworks should I try?

Note that this post is about integration/e2e tests. So, I do not want to mock away anything (as numerous answers to similar questions suggest). I really do want to test the interactions between the two windows (and ideally discard the new window afterwards).

I have a small webapp that opens a link in a new window. The document in the new window then interacts with the original webapp through the DOM.

The webapp itself is written in Angular, but the link is plain HTML (not even coming from an Angular template). The target document is not Angular, just plain HTML/CSS/JS:

  <a target="_blank" rel="opener" href="/assets/probes/xss.html">Click here!</a>

Tests are set up according to Angular's component testing guide. Here's a snippet of the setup code:

  beforeEach(async () => {
    TestBed.configureTestingModule(xssDemoConfig);
    await TestBedpileComponents();
    fixture = TestBed.createComponent(XssDemoComponent);
    fixture.detectChanges();

    // ...
  });

This setup works like a charm for hundreds of other tests. The new test code is simple:

  el.querySelector('a').click();

I've confirmed in the browser debug console that the selector returns the correct <a> element. (And I have other working tests that trigger click events on similar links — only difference is that those links have javascript: URLs and do not open a new window or even trigger navigation.)

Everything works like a charm when testing manually in a browser. However, when my new tests try to click the link, nothing at all happens. No new window, but no error or log message either. My spec just runs into a timeout. (I've tried more generous timeouts, but this hasn't fixed it.)

So, finally my questions:

  • Why is this happening?
  • Does the Angular TestBed, or Jasmine, or Karma have some hidden feature that intercepts such clicks?
  • If so, which of them is at fault here?
  • Is there any way that I could bypass this undesired behavior?
  • Is such testing feasible with Karma/Jasmine at all?
  • If not, which other tools/frameworks should I try?

Note that this post is about integration/e2e tests. So, I do not want to mock away anything (as numerous answers to similar questions suggest). I really do want to test the interactions between the two windows (and ideally discard the new window afterwards).

Share Improve this question edited Feb 25 at 10:10 VLAZ 29.1k9 gold badges62 silver badges84 bronze badges asked Feb 24 at 19:14 meequemeeque 133 bronze badges 4
  • Btw, I'm aware that the webapp that I'm trying to test here is doing something rather weird. But no, I don't want to re-engineer the webapp itself. It's a demo/educational webapp that wants to show just this. Only problem is the testing:( – meeque Commented Feb 24 at 19:20
  • Too long. Condense the question. – Cymro Commented Feb 24 at 20:19
  • It's a demo/educational webapp This already should be a reason to not over-engineer a test. Karma / Jasmine suite is really bad and do a poor job when testing scenarios between iFrame / not native window. Consider using Jest, Angular Testing Library, Storybook or other alternative that are way stable and reliable, if you really want to test a demo/educational app. – Jacopo Sciampi Commented Feb 25 at 9:56
  • Thanks for the pointers @jacopo-sciampini! Since Karma is eol now, I'll have to look for alternatives anyway. However, your proposals seem to mock away a lot by default, so I might run into similar trouble when dealing with new windows. I'd also prefer to run my tests in a real browser. Maybe using Jest with Puppeteer is a viable approach. Or good old Selenium... For now, Karma/Jasmine is giving me 98% of what I want. Still curious how to solve my specific problem here, but I might as well leaver it as is. – meeque Commented Feb 25 at 19:47
Add a comment  | 

1 Answer 1

Reset to default 0

Found the solution myself:

It was a browser issue all along. Karma/Jasmine are behaving just fine, and open links in a new window/tab as my tests intend.

Instead, the browser's popup blocker was at fault. I had thought that I had ruled out popup blockers before posting here, because I did not see any notifications about blocked windows. Turns out that Chromium (which I used for testing) does not show such notifications, but Firefox does. At least in my respective configurations.

Setting up exception rules has resolved the issue for both browsers.

My bad.

本文标签: