Skip to content

Tests: Fix flakiness in the "jQuery.ajax() - JSONP - Same Domain" test #4687

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

Merged
merged 1 commit into from
Apr 27, 2020

Conversation

mgol
Copy link
Member

@mgol mgol commented Apr 24, 2020

Summary

The "jQuery.ajax() - JSONP - Same Domain" test is firing a request with
a duplicate "callback" parameter, something like (simplified):

mock.php?action=jsonp&callback=jQuery_1&callback=jQuery_2

There was a difference in how the PHP & Node.js implementations of the jsonp
action in the mock server handled situations like that. The PHP implementation
was using the latest parameter while the Node.js one was turning it into an
array but the code didn't handle this situation. Because of how JavaScript
stringifies arrays, while the PHP implementation injected the following code:

jQuery_2(payload)

the Node.js one was injecting the following one:

jQuery_1,jQuery_2(payload)

This is a comma expression in JavaScript; it so turned out that in the majority
of cases both callbacks were identical so it was more like:

jQuery_1,jQuery_1(payload)

which evaluates to jQuery_1(payload) when jQuery_1 is defined, making the
test go as expected. In many cases, though, especially on Travis, the callbacks
were different, triggering an Uncaught ReferenceError error & requiring
frequent manual re-runs of Travis builds.

This commit fixes the logic in the mock Node.js server, adding special handling
for arrays.

Checklist

The "jQuery.ajax() - JSONP - Same Domain" test is firing a request with
a duplicate "callback" parameter, something like (simplified):
```
mock.php?action=jsonp&callback=jQuery_1&callback=jQuery_2
```

There was a difference in how the PHP & Node.js implementations of the jsonp
action in the mock server handled situations like that. The PHP implementation
was using the latest parameter while the Node.js one was turning it into an
array but the code didn't handle this situation. Because of how JavaScript
stringifies arrays, while the PHP implementation injected the following code:
```js
jQuery_2(payload)
```
the Node.js one was injecting the following one:
```js
jQuery_1,jQuery_2(payload)
```
This is a comma expression in JavaScript; it so turned out that in the majority
of cases both callbacks were identical so it was more like:
```js
jQuery_1,jQuery_1(payload)
```
which evaluates to `jQuery_1(payload)` when `jQuery_1` is defined, making the
test go as expected. In many cases, though, especially on Travis, the callbacks
were different, triggering an `Uncaught ReferenceError` error & requiring
frequent manual re-runs of Travis builds.

This commit fixes the logic in the mock Node.js server, adding special handling
for arrays.
@mgol mgol added this to the 3.5.1 milestone Apr 24, 2020
@mgol mgol self-assigned this Apr 24, 2020
@mgol
Copy link
Member Author

mgol commented Apr 24, 2020

An example failing build (with some debug logging details): https://travis-ci.org/github/jquery/jquery/jobs/678811015

You can see the error in the logs:

HeadlessChrome 81.0.4044 (Linux 0.0.0) ERROR
  {
    "message": "Uncaught ReferenceError: jQuery008281692735376822_1587716819366 is not defined\nat test/data/mock.php=jsonp&callback=jQuery008281692735376822_1587716819366&&callback=jQuery008281692735376822_1587716819395&_=1587716819423:1:1\n\nReferenceError: jQuery008281692735376822_1587716819366 is not defined\n    at test/data/mock.php=jsonp&callback=jQuery008281692735376822_1587716819366&&callback=jQuery008281692735376822_1587716819395&_=1587716819423:1:1",
    "str": "Uncaught ReferenceError: jQuery008281692735376822_1587716819366 is not defined\nat test/data/mock.php=jsonp&callback=jQuery008281692735376822_1587716819366&&callback=jQuery008281692735376822_1587716819395&_=1587716819423:1:1\n\nReferenceError: jQuery008281692735376822_1587716819366 is not defined\n    at test/data/mock.php=jsonp&callback=jQuery008281692735376822_1587716819366&&callback=jQuery008281692735376822_1587716819395&_=1587716819423:1:1"
  }
HeadlessChrome 81.0.4044 (Linux 0.0.0): Executed 771 of 1079 (skipped 1) ERROR (33.753 secs / 23.364 secs)

@mgol
Copy link
Member Author

mgol commented Apr 24, 2020

It took me a few months of fighting with this issue to finally take the time to find the culprit. 😅

Copy link
Member

@dmethvin dmethvin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your persistence paid off!

@mgol mgol removed the Needs review label Apr 27, 2020
@mgol mgol merged commit 7b0864d into jquery:master Apr 27, 2020
@mgol mgol deleted the jsonp-test-flakiness branch April 27, 2020 18:22
mgol added a commit that referenced this pull request Apr 27, 2020
The "jQuery.ajax() - JSONP - Same Domain" test is firing a request with
a duplicate "callback" parameter, something like (simplified):
```
mock.php?action=jsonp&callback=jQuery_1&callback=jQuery_2
```

There was a difference in how the PHP & Node.js implementations of the jsonp
action in the mock server handled situations like that. The PHP implementation
was using the latest parameter while the Node.js one was turning it into an
array but the code didn't handle this situation. Because of how JavaScript
stringifies arrays, while the PHP implementation injected the following code:
```js
jQuery_2(payload)
```
the Node.js one was injecting the following one:
```js
jQuery_1,jQuery_2(payload)
```
This is a comma expression in JavaScript; it so turned out that in the majority
of cases both callbacks were identical so it was more like:
```js
jQuery_1,jQuery_1(payload)
```
which evaluates to `jQuery_1(payload)` when `jQuery_1` is defined, making the
test go as expected. In many cases, though, especially on Travis, the callbacks
were different, triggering an `Uncaught ReferenceError` error & requiring
frequent manual re-runs of Travis builds.

This commit fixes the logic in the mock Node.js server, adding special handling
for arrays.

Closes gh-4687

(cherry picked from commit 7b0864d)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy