Open Bug 1842614 Opened 2 years ago Updated 1 month ago

"Feedback" button is missing at southwest.com

Categories

(Web Compatibility :: Site Reports, defect, P3)

Firefox 117
Desktop
Windows 10

Tracking

(Webcompat Priority:P2)

Webcompat Priority P2

People

(Reporter: rbucata, Unassigned)

References

(Blocks 1 open bug, )

Details

(Keywords: webcompat:needs-contact, webcompat:needs-sitepatch, webcompat:site-report, Whiteboard: [webcompat:sightline])

User Story

platform:windows,mac,linux,android
impact:feature-broken-minor
configuration:general
affects:all
branch:release

Attachments

(1 file)

Attached image Screenshot_1.png

Environment:
Operating System: Windows 10 PRO x64
Firefox version: Firefox Nightly 117.0a1 (2023-07-09) (64-bit)

Preconditions:
Clean profile

Steps to reproduce:

  1. Navigate to: https://www.southwest.com/
  2. Scroll the page up and down.
  3. Observe the right part of the page, next to the scrollbar.

Expected Behavior:
The "Feedback" button is present.

Actual Behavior:
The "Feedback" button is missing.

Notes:

  • Reproducible regardless of the status of ETP.
  • Reproducible on the latest build of Firefox Nightly and Release.
  • Works as expected using Chrome.

Verified this issue and it's still reproducible on Firefox versions 122 and 124.

Environment:
Operating system: Windows 10
Browsers: Firefox Nightly 124.0a1 (2024-01-29) / Firefox Release 122 / Chrome 121.0.6167.86

Note: Not reproducible on Chrome

Severity: -- → S3
Priority: P3 → P2
Severity: S3 → S4
User Story: (updated)
Priority: P2 → P3

In Chrome, the button is revealed in https://siteintercept.qualtrics.com/dxjsmodule/1.c51ad4dbeb224a512030.chunk.js?Q_CLIENTVERSION=2.18.1&Q_CLIENTTYPE=web&Q_BRANDID=southwest:

                    resetStyle: p("QSIFeedbackButton")

I don't even see that file in Firefox's network panel, so it's not being loaded. The code to load it is #10 in the list below:

    function i(e) {
      var n = window.QSI.__webpack_get_script_src__,
      t = function (e) {
        return r.p + '' + ({
        }
        [
          e
        ] || e) + '.' + {
          0: '4bc342893f8e9e8c986d',
          1: 'c51ad4dbeb224a512030',
          2: 'ffc19d7ec7dcdb28338d',
          3: '1d724e34f90272a07c1e',
          4: 'd7b2785dd120c40d6d05',
          5: 'af7c62ed24f3109ccdf9',
          7: '0ce7c45840e16b27b175',
          8: '5523a0bc5d7bd072a82a',
          9: '8d9c591aa71c24740b41',
          10: '1ba09b50c5c5f3299692',
          11: '8efb72b94576d776724b',
          12: '2ccba825ea0bd3d6be05',
          13: 'acbbc28c1f1ff17d6dd9',
          14: 'b61ba5aa618c89931455',
          15: 'ef42721609c93455d965',
          16: '1ef8051214a9eba39181',
          17: '9feafc8b02c6197b1d39',
          18: '440e745a33b2120c5b79',
          19: '97f54c610a83364f8840',
          20: '53835a58e90ac4e9ad0d',
          21: '99d952e49e53c854cce2',
          22: 'eb766f2150408097dbc1'
        }

So something is probably preventing it from being loaded, and is likely causing other errors given the list of scripts here.

I looked at the initiator trace in the Chrome network panel, and found that Firefox isn't getting very far; it gets to this code in their WRSiteInterceptEngine and call initialize:

        window.QSI_TESTING_MODE ||
        (
          document.currentScript &&
          (e = document.currentScript.src),
          t.e(10).then(t.bind(null, 74)).then((function (n) {
            (0, n.initialize) (e)
          }))
        )

But a global search for QSI.AssetManager which is later in the trace, shows nothing, so that script isn't loaded either.

User Story: (updated)

The script that loads this is:

        r.e = function(e) {
            var n = []
              , t = o[e];
            if (0 !== t)
                if (t)
                    n.push(t[2]);
                else {
                    var a = new Promise((function(n, i) {
                        t = o[e] = [n, i]
                    }
                    ));
                    n.push(t[2] = a);
                    var d, c = document.createElement("script");
                    c.charset = "utf-8",
                    c.timeout = 120,
                    r.nc && c.setAttribute("nonce", r.nc),
                    c.src = i(e);
                    var s = new Error;
                    d = function(n) {
                        c.onerror = c.onload = null,
                        clearTimeout(l);
                        var t = o[e];
                        if (0 !== t) {
                            if (t) {
                                var i = n && ("load" === n.type ? "missing" : n.type)
                                  , r = n && n.target && n.target.src;
                                s.message = "Loading chunk " + e + " failed.\n(" + i + ": " + r + ")",
                                s.type = i,
                                s.request = r,
                                t[1](s)
                            }
                            o[e] = void 0
                        }
                    }
                    ;
                    var l = setTimeout((function() {
                        d({
                            type: "timeout",
                            target: c
                        })
                    }
                    ), 12e4);
                    c.onerror = c.onload = d,
                    document.head.appendChild(c)
                }
            return Promise.all(n)

That script gets loaded from https://www.southwest.com/swa-resources/scripts/analytics/analytics.js

    extensions: {
        "qualtrics-website-feedback": {
            displayName: "Qualtrics Website Feedback",
            hostedLibFilesBaseUrl: "/swa-resources/scripts/analytics//b52dfd6476cb/21df05686c51/c3950aba181e/hostedLibFiles/EP3037080b2f514c82a49a8eab77b5a00e/",
            modules: {
                "qualtrics-website-feedback/src/lib/actions/loadProject.js": {
                    name: "load-project",
                    displayName: "Load Project",
                    script: function(e, t, a, r) {
                        "use strict";
                        e.exports = function(e) {
                            try {
                                var t = e.brandID
                                  , a = e.projectID
                                  , s = a.replace("_", "").toLowerCase()
                                  , n = function() {
                                    var e = document.createElement("div");
                                    e.id = a,
                                    document.body.appendChild(e)
                                };
                                void 0 === window.QSI && (window.QSI = {
                                    clientTypeVariant: "AdobeLaunch"
                                });
                                var i = function() {
                                    !function() {
                                        var e = function(e, t, a, r) {
                                            this.get = function(e) {
                                                for (var t = e + "=", a = document.cookie.split(";"), r = 0, s = a.length; r < s; r++) {
                                                    for (var n = a[r]; " " == n.charAt(0); )
                                                        n = n.substring(1, n.length);
                                                    if (0 == n.indexOf(t))
                                                        return n.substring(t.length, n.length)
                                                }
                                                return null
                                            }
                                            ,
                                            this.set = function(e, t) {
                                                var a, r = "";
                                                (a = new Date).setTime(a.getTime() + 6048e5),
                                                r = "; expires=" + a.toGMTString(),
                                                document.cookie = e + "=" + t + r + "; path=/; "
                                            }
                                            ,
                                            this.check = function() {
                                                var r = this.get(a);
                                                if (r)
                                                    r = r.split(":");
                                                else {
                                                    if (r = [t, e, 0],
                                                    100 == e)
                                                        return !0;
                                                    "v" == t && (e = Math.random() >= e / 100 ? 0 : 100),
                                                    r = [t, e, 0],
                                                    this.set(a, r.join(":"))
                                                }
                                                var s = r[1];
                                                if (100 == s)
                                                    return !0;
                                                switch (r[0]) {
                                                case "v":
                                                    return !1;
                                                case "r":
                                                    var n = r[2] % Math.floor(100 / s);
                                                    return r[2]++,
                                                    this.set(a, r.join(":")),
                                                    !n
                                                }
                                                return !0
                                            }
                                            ,
                                            this.go = function() {
                                                if (this.check()) {
                                                    var e = document.createElement("script");
                                                    e.type = "text/javascript",
                                                    e.src = r,
                                                    document.body && document.body.appendChild(e)
                                                }
                                            }
                                        };
                                        try {
                                            new e(100,"r","QSI_S_" + a,"https://" + s + "-" + t + ".siteintercept.qualtrics.com/WRSiteInterceptEngine/?Q_ZID=" + a).go()
                                        } catch (e) {}
                                    }()
                                };
                                t && a && s && (n(),
                                i(),
                                r.logger.log("Loaded Site Intercept Project: " + a))
                            } catch (e) {
                                r.logger.error("Could not load Intercept Project: " + e)
                            }
                        }
                    }
                }
            }
        },

So this.check() returns false, because e == 100 and there's no cookie (QSI_S_ZN_6fEtw4RXYKndJOZ is the cookie they're looking for)... But that cookie I don't see in chrome either.

Wait that returns true, nvm

I'm seeing a difference over here:
https://siteintercept.qualtrics.com/dxjsmodule/10.397ed61a8c9d10842d69.chunk.js?Q_CLIENTVERSION=2.19.0&Q_CLIENTTYPE=web&Q_BRANDID=www.southwest.com
(warning the sha changes over time, so Tom sha changed, and mine [397ed61a8c9d10842d69] will change)

                    var o = QSI.Orchestrator.Deferred()
                      , i = new XMLHttpRequest;
                    return i.open(e, t, !0),
                    i.withCredentials = !0,
                    "POST" === e && i.setRequestHeader("Content-type", "application/x-www-form-urlencoded"),
                    i.onreadystatechange = function() {
                        4 === i.readyState && (200 === i.status ? o.resolve(i.responseText) : o.reject(i.responseText))
                    }
                    ,
                    i.send(n),
                    o.promise()

i.responseText is different and explains why we have a difference and why the feedback button is explicitely disabled.
It is a JSON string which contains a "ActionSets" Array, which is empty on Firefox whereas it contains the following object on chrome:

                {
                    "ActionSetID": "AS_07676101",
                    "ContactFrequencyPassed": null,
                    "Creative": {
                        "AnchorTags": {
                        },
                        "ID": "CR_2gJhqDWQ54wnbM1",
                        "Name": "Feedback Button: Slider",
                        "Revision": "35",
                        "Type": "FeedbackButton"
                    },
                    "Label": "Production Action Set",
                    "LogicTree": {
                        "Left": {
                            "Comparator": "GTE",
                            "Left": {
                                "Expression": "BrowserWidth",
                                "LogicType": "Resolution",
                                "Type": "LogicNode"
                            },
                            "Right": {
                                "Type": "ValueNode",
                                "Value": "978"
                            },
                            "Type": "ComparatorNode"
                        },
                        "Operator": "AND",
                        "Right": {
                            "Comparator": "HAS_NOT_BEEN_SEEN",
                            "Left": {
                                "InterceptIDs": [
                                    "SI_6mMvcazi0l24rS5"
                                ],
                                "LogicType": "InterceptLogic",
                                "Type": "LogicNode"
                            },
                            "Right": {
                                "Type": "ValueNode",
                                "Value": "2592000"
                            },
                            "Type": "ComparatorNode"
                        },
                        "Type": "ConjunctionNode"
                    },
                    "PopUnderTarget": null,
                    "SurveyID": "SV_39R4UghEgZNZfFz",
                    "Target": {
                        "DisplayType": null,
                        "OriginalURL": "https://www.surveysouthwest.com/jfe/form/SV_39R4UghEgZNZfFz?Q_CHL=si",
                        "OriginalURLOrigin": "https://www.surveysouthwest.com",
                        "Type": "Survey",
                        "URL": "https://siteintercept.qualtrics.com/WRSiteInterceptEngine/?Q_CLIENTTYPE=webAdobeLaunch&Q_Redirect=https://www.surveysouthwest.com/jfe/form/SV_39R4UghEgZNZfFz?Q_CHL%3Dsi&Q_CID=CR_2gJhqDWQ54wnbM1&Q_ASID=AS_07676101&Q_SRT=RH103T1V4Mw8V42XGKHb8w%3D%3D&Q_SIID=SI_5yVw4GOJpYx0RUx&Q_LOC=https://www.southwest.com/&Q_CLIENTVERSION=2.19.0"
                    }
                }

This JSON is fetched from the following URL:
https://siteintercept.qualtrics.com/WRSiteInterceptEngine/Targeting.php?Q_ZoneID=ZN_6fEtw4RXYKndJOZ&Q_CLIENTVERSION=2.19.0&Q_CLIENTTYPE=webAdobeLaunch.

You can see the difference via the network monitor. You won't see Feedback Button in Firefox while you will on Chrome.

Changing the user agent for chrome's one and then, I get the Feedback Button in that JSON...

For some reason, chrome mask doesn't seem to impact this request and we keep Firefox one.
Is that expected?

(In reply to Alexandre Poirot [:ochameau] from comment #10)

For some reason, chrome mask doesn't seem to impact this request and we keep Firefox one.
Is that expected?

I don't think so. Dennis?

Flags: needinfo?(dschubert)

Sounds like possibly 2 issues: 1 chromemask may not be affecting all requests. 2 the site is purposely not giving us the feedback code. The second is an outreach issue. I wonder if we can ship an intervention, though

Whiteboard: [webcompat:sightline]

(In reply to Jeff Muizelaar [:jrmuizel] from comment #11)

I don't think so. Dennis?

Kinda expected in the current implementation. Let's move this discussion to over here, where I highlighted the reason, and possible solutions.

Flags: needinfo?(dschubert)
Webcompat Priority: --- → P2
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: