0

Objective:

  • check navigator.userAgent
  • do a simple UI change based on userAgent

Findings:

the logic works as intended on:

  • real iOS device
  • chrome emulator
  • firefox emulator
chrome firefox cypress (PROBLEM)
Chrome works as intended firefox cypress-problem

Problem:

  • in cypress, even though navigator.userAgent is correct, UI logic is not triggered

COMPLETE PROJECT REPO HERE

relevant code for using userAgent inside cypress:

const { defineConfig } = require("cypress");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      // implement node event listeners here
    },
    userAgent:
      "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
  },
});

code for UI logic:

const isiOSDevice = () =>
  navigator.vendor === "Apple Computer, Inc." ||
  (/iPad|iPhone|iPod/.test(navigator.userAgent) &&
    !window.MSStream &&
    "ontouchend" in document);

function App() {
  const isIOS = isiOSDevice();

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <div className={`ios-${isIOS}`}>
          <p>
            are we on iOS device? <code>{isIOS.toString()}</code>
            <br /> navigator.userAgent is: {navigator.userAgent}
          </p>
          {isIOS ? (
            <p>
              hence we would see <span>blue</span> color
            </p>
          ) : (
            <p>
              hence we would see <span>red</span> color
            </p>
          )}
        </div>
      </header>
    </div>
  );
}
Akber Iqbal
  • 14,487
  • 12
  • 48
  • 70

2 Answers2

2

Instead of testing for touchend I use navigator.maxTouchPoints, but I can't say it's definitive either way. I have a WinOS & touch screen.

const isiOSDevice = () =>
  navigator.vendor === "Apple Computer, Inc." ||
  (/iPad|iPhone|iPod/.test(navigator.userAgent) &&
    !window.MSStream &&
    navigator.maxTouchPoints > 1)
TesterDick
  • 3,830
  • 5
  • 18
1

Firstly, appreciate a reproducible repo to help out on this question.

The issue is in your isiOSDevice() primarily the "ontouchend" in document, which returns undefined for Canary, Chrome, Electron, and Firefox.

I removed that part of the logic on local and was able to get iOS device as true and blue. Also, added console logging of the values as proof. enter image description here

jjhelguero
  • 2,281
  • 5
  • 13