Add installation instructions for not iOS
Test / test (push) Failing after 2m12s Details

This commit is contained in:
Jeff 2024-09-25 14:09:30 -04:00
parent e86534dc86
commit c1cfdb78de
9 changed files with 109 additions and 34 deletions

View File

@ -7,4 +7,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install && npm run test && npx playwright test
- run: npm install && npm run test && npx playwright install && npx playwright test

View File

@ -13,7 +13,7 @@
"*.spec.js"
],
"options": {
"maxLineLength": 9999999
"maxLineLength": 9999
}
}
]

View File

@ -1,6 +1,7 @@
import React from "react"
import { useEffect } from "react"
import { usePush } from "../usePush"
import { request } from "http"
export default function EnableNotifications({
onSubscribe,

View File

@ -9,6 +9,7 @@ import PermissionDenied from "./PermissionDenied"
interface InstallPromptsProps {
isMobileSafari: boolean
isSupported: boolean
isIOS: boolean
notificationsEnabled: boolean
onInstallComplete: () => void
}
@ -16,9 +17,10 @@ interface InstallPromptsProps {
export default function InstallPrompts({
isSupported,
isMobileSafari,
isIOS,
onInstallComplete,
}: InstallPromptsProps) {
const { step } = useInstallState({ isSupported, isMobileSafari })
const { step } = useInstallState({ isSupported, isMobileSafari, isIOS })
const steps = {
"open safari": <OpenSafari />,

View File

@ -3,11 +3,16 @@ import React from "react"
export default function PermissionDenied() {
return (
<div>
<h1>Enable Notifications</h1>
<div>
<span>Tack Up Now</span> requires notifications permissions to work
<span className="bold">Tack Up Now</span> requires notifications
permissions to work
</div>
<br />
<div>Grant notifications permissions to use Tack Up Now</div>
<div>
You have denied permission to send notifications, please grant
notifications permissions to use Tack Up Now
</div>
</div>
)
}

View File

@ -14,7 +14,11 @@ describe("root", () => {
path: "/",
meta: () => [],
links: () => [],
loader: () => ({ isSupported: true, isMobileSafari: true }),
loader: () => ({
isSupported: true,
isMobileSafari: true,
isIOS: true,
}),
Component: Index,
},
])

View File

@ -28,28 +28,25 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
os.name !== "iOS" ||
versionAtLeast(coerceSemver(os.version) ?? "0.0.0", "16.4.0")
const isIOS = os.name === "iOS"
return json({
isSupported,
isMobileSafari,
name: os.name,
version: os.version,
isIOS,
})
}
export default function Index() {
const { isSupported, isMobileSafari, name, version } =
useLoaderData<typeof loader>()
console.log(name, version)
const { isSupported, isMobileSafari, isIOS } = useLoaderData<typeof loader>()
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
<Suspense>
<LandingMessage
isSupported={isSupported}
isMobileSafari={isMobileSafari}
/>
</Suspense>
<LandingMessage
isSupported={isSupported}
isMobileSafari={isMobileSafari}
isIOS={isIOS}
/>
</div>
)
}
@ -57,11 +54,13 @@ export default function Index() {
function LandingMessage({
isSupported,
isMobileSafari,
isIOS,
}: {
isSupported: boolean
isMobileSafari: boolean
isIOS: boolean
}) {
const { installed } = useInstallState({ isSupported, isMobileSafari })
const { installed } = useInstallState({ isSupported, isMobileSafari, isIOS })
const [isInstalled, setIsInstalled] = useState(installed)
@ -74,6 +73,7 @@ function LandingMessage({
<InstallPrompts
isMobileSafari={isMobileSafari}
isSupported={isSupported}
isIOS={isIOS}
notificationsEnabled={false}
onInstallComplete={() => setIsInstalled(true)}
/>

View File

@ -11,9 +11,11 @@ type IOSInstallStep =
export default function useInstallState({
isSupported,
isMobileSafari,
isIOS,
}: {
isSupported: boolean
isMobileSafari: boolean
isIOS: boolean
}) {
const isClient = typeof window !== "undefined"
@ -37,18 +39,25 @@ export default function useInstallState({
("standalone" in navigator && (navigator.standalone as boolean)) ||
matchMedia("(dislay-mode: standalone)").matches
const iOSStates = [
state(!isMobileSafari, "open safari"),
state(!isRunningPWA, "install"),
]
const states = [
state(!isSupported, "unsupported"),
...(isIOS ? iOSStates : []),
state(permissionDenied, "permission denied"),
state(!notificationsEnabled, "enable notifications"),
]
return {
step: !isSupported
? "unsupported"
: !isMobileSafari
? "open safari"
: !isRunningPWA && isMobileSafari
? "install"
: permissionDenied
? "permission denied"
: !notificationsEnabled
? "enable notifications"
: (null as IOSInstallStep | null),
step: states.find(({ active }) => active)?.result ?? null,
installed: notificationsEnabled,
}
}
const state = (active: boolean, result: IOSInstallStep) => ({
active,
result,
})

View File

@ -8,6 +8,12 @@ function webkitOnly() {
})
}
function nonWebkitOnly() {
beforeEach(async ({ browserName }) => {
if (browserName === "webkit") skip()
})
}
describe("when user is on iOS", () => {
webkitOnly()
@ -108,7 +114,6 @@ describe("when user is on iOS", () => {
await page.goto("/")
const deniedText = page.getByText(/requires notifications permissions/)
await expect(deniedText).toBeAttached()
})
@ -156,10 +161,59 @@ describe("when user is on iOS", () => {
})
describe("other browsers", () => {
describe("when notifications permissions are unknown", () => {
test("prompt the user to allow notifications", async ({ page }) => {
// await page.
nonWebkitOnly()
beforeEach(async ({ page }) => {
await page.route("/api/subscribe", async (route) => {
await route.fulfill()
})
await stubServiceWorker(page)
})
test("prompt the user to allow notifications", async ({ page }) => {
await stubNotifications(page, { permission: "default" })
await page.goto("/")
const notificationText = page.getByText(/Enable Notifications/)
await expect(notificationText).toBeAttached()
})
test("show tack up now when permission is granted", async ({ page }) => {
await stubNotifications(page, { permission: "granted" })
await page.goto("/")
const yourNotificationsHeading = page.getByText(/Your Notifications/)
await expect(yourNotificationsHeading).toBeVisible()
})
test("submit the push subscription on permission granted", async ({
page,
}) => {
await stubNotifications(page, {
permission: "default",
requestPermissionResult: "granted",
})
await page.goto("/")
const requestPromise = page.waitForRequest("/api/subscribe")
await page.getByText(/Enable Notifications/).click()
const request = await requestPromise
await expect(request.postDataJSON()).toEqual({ hi: "subscription" })
})
test("prompt to allow notifications if permission was denied", async ({
page,
}) => {
await stubNotifications(page, { permission: "denied" })
await page.goto("/")
const deniedText = page.getByText(/requires notifications permissions/)
await expect(deniedText).toBeAttached()
})
})