Vérifier l’isolation des sessions WKWebView sur un Mac distant

Vérifier l’isolation des sessions WKWebView sur un Mac distant

Lorsqu’une équipe exécute des tests de régression iOS sur un Mac distant, l’application peut ouvrir successivement deux sessions Web : elle se connecte d’abord à l’espace de travail A, puis passe à l’espace de travail B. Si B lit un cookie de A, l’interface peut sembler se charger normalement ; le problème ne se révélera qu’au changement d’identité. Plutôt que de vérifier uniquement que « la page s’ouvre », mieux vaut commencer par un test reproductible de la séparation entre les stockages de données des sites Web.

Définir d’abord ce qu’il faut isoler

WKWebView sélectionne le stockage des données des sites Web au moyen de WKWebViewConfiguration.websiteDataStore. WKWebsiteDataStore.default() correspond aux données persistantes ; chaque appel à WKWebsiteDataStore.nonPersistent() peut créer une instance de stockage temporaire. Ici, nous vérifions d’abord l’isolation des cookies entre deux stockages temporaires distincts, sans y voir une preuve que l’ensemble du parcours de connexion est sécurisé.

Avant d’écrire le test, repérez dans le code de l’application où les vues Web sont créées et notez le stockage associé à chacune. Si plusieurs pages d’une même identité doivent partager une session, elles ne doivent pas utiliser par erreur des stockages temporaires distincts. Si un changement d’identité doit repartir de zéro, vérifiez que la nouvelle vue ne référence plus l’ancien stockage. Consigner dans un tableau « quelles pages partagent leur stockage et lesquelles restent séparées » est plus fiable que de chercher après coup l’origine d’un cookie.

WKProcessPool n’est pas l’objet du contrôle ici. Ne concluez pas au partage ou à l’isolation des données des sites Web à partir de la seule identité du pool de processus : vérifiez le websiteDataStore effectivement associé à chaque vue.

Écrire un test de stockage sans dépendance à Internet

Importez WebKit et XCTest dans le target de tests unitaires de l’application. Le test ci-dessous ne manipule que le stockage des cookies et n’émet aucune requête réseau : il ne nécessite donc ni serveur de test ni chargement rapide des pages. test.invalid sert de domaine au cookie d’exemple, pas d’adresse de service.

import WebKit
import XCTest

final class WebsiteDataIsolationTests: XCTestCase {
    func testEphemeralStoresDoNotShareCookie() {
        let storeA = WKWebsiteDataStore.nonPersistent()
        let storeB = WKWebsiteDataStore.nonPersistent()
        let done = expectation(description: "Both stores checked")

        guard let cookie = HTTPCookie(properties: [
            .domain: "test.invalid",
            .path: "/",
            .name: "isolation_probe",
            .value: "only_a"
        ]) else {
            XCTFail("Could not create probe cookie")
            return
        }

        storeA.httpCookieStore.setCookie(cookie) {
            storeA.httpCookieStore.getAllCookies { cookiesA in
                XCTAssertTrue(cookiesA.contains {
                    $0.name == "isolation_probe" && $0.value == "only_a"
                })

                storeB.httpCookieStore.getAllCookies { cookiesB in
                    XCTAssertFalse(cookiesB.contains {
                        $0.name == "isolation_probe"
                    })
                    done.fulfill()
                }
            }
        }

        wait(for: [done], timeout: 5)
    }
}

Vérifiez d’abord que A peut lire la valeur qui vient d’être écrite, puis que B ne voit pas le cookie du même nom. Cet ordre compte : si vous lisez B avant la fin de l’écriture, le test pourrait « réussir » même si les deux stockages partagent les données à tort. Un dépassement du délai signifie que la chaîne de rappels ne s’est pas achevée ; il faut en rechercher la cause, pas augmenter indéfiniment le délai.

Rattacher le stockage aux pages réelles

Une fois le test de la couche de stockage réussi, examinez la façon dont l’application crée ses vues. La configuration doit être définie avant l’initialisation de WKWebView : modifier ensuite une autre configuration ne changera pas le stockage d’une vue déjà créée. Le code de préparation d’un test de page peut transmettre explicitement l’instance voulue :

let sessionStore = WKWebsiteDataStore.nonPersistent()
let configuration = WKWebViewConfiguration()
configuration.websiteDataStore = sessionStore
let webView = WKWebView(frame: .zero, configuration: configuration)

Les tests d’intégration suivants doivent charger une page de test sous votre contrôle, lui faire effectuer une connexion, lire l’état de la session, changer d’identité et se déconnecter, puis observer les requêtes et l’affichage. L’API de stockage permet de démontrer qu’un cookie de test n’est pas visible d’une instance à l’autre. À elle seule, elle ne prouve ni l’invalidation de la session côté serveur ni l’absence de réinjection d’un jeton dans la page par la couche native de l’application. Si le test exige de vraies requêtes, utilisez un service contrôlé et maintenu par l’équipe, et consignez séparément les défaillances réseau et les assertions sur la session.

Tester séparément le stockage persistant

Ne déduisez pas d’un test réussi avec nonPersistent() que la déconnexion fonctionne correctement. Si l’application utilise default(), le test de déconnexion doit vérifier que les données pertinentes du stockage persistant sont traitées selon les règles du produit, puis répéter la vérification après avoir recréé la vue Web. Délimitez les données à supprimer avant tout nettoyage : n’effacez pas indistinctement des enregistrements dont d’autres pages de l’appareil pourraient encore avoir besoin dans le seul but de faire passer le test.

Garder des résultats reproductibles sur un Mac distant

Exécutez le même target de tests sur le poste de développement et dans les tâches automatisées, en conservant les résultats de chaque exécution. Avant le lancement, fixez la version de Xcode, celle du système du simulateur et la configuration de test exigées par le projet ; il n’est pas nécessaire de supposer qu’une version donnée du système convient dans tous les cas. Recréez les stockages temporaires dans chaque méthode de test et donnez un nom dédié au cookie de test pour éviter que les cas de test ne réutilisent l’état des autres.

Si « le test réussit seul, mais échoue avec toute la suite », vérifiez d’abord trois points : le test est-il passé à default() sans que vous l’ayez remarqué ? Les deux vues Web réutilisent-elles la même instance de stockage ? L’écriture asynchrone, la navigation et les assertions sont-elles ordonnées selon les rappels de fin d’opération ? N’allongez pas d’emblée les délais d’attente pour masquer le problème. Pour pouvoir analyser l’échec ultérieurement, conservez le nom du cas de test, les versions de Xcode et du simulateur utilisées, ainsi que le fichier de résultats. N’inscrivez pas de véritables valeurs de session dans les journaux.

Points à vérifier avant livraison

Point à vérifier Critère de réussite
Stockage associé Le websiteDataStore de chaque vue Web correspond à la session attendue
Isolation temporaire Le cookie de test écrit dans A n’est pas visible dans B, qui est indépendant
Ordre des rappels Lire A après la fin de l’écriture, puis lire B
Vérification de la déconnexion Contrôler séparément les données persistantes et la session côté serveur selon les règles du produit
Éléments en cas d’échec Consigner l’environnement et les assertions, sans enregistrer de véritables identifiants

Cette démarche est surtout utile comme test de frontière : démontrez d’abord que les données locales ne circulent pas entre les stockages temporaires, puis validez le changement d’identité et la déconnexion avec des tests au niveau des pages. Consignez séparément les conclusions de ces deux niveaux : en cas d’échec, vous saurez s’il faut examiner l’association des stockages, l’ordre des opérations asynchrones ou la logique de session propre à l’application.

Questions fréquentes

Un stockage temporaire efface-t-il les cookies persistants ?

Non. nonPersistent() ne nettoie pas default(). Le parcours de déconnexion doit vérifier séparément le stockage persistant réellement utilisé.

Deux WKProcessPool distincts suffisent-ils à isoler les cookies ?

Il ne faut pas le supposer. Vérifiez le WKWebsiteDataStore associé à chaque vue, puis testez les requêtes et l’état observé par la page si nécessaire.

XCZone · Mac dans le cloud

Besoin d’un Mac physique dédié accessible à distance ?

Comparez les configurations, les emplacements et les périodes de facturation de M4 Start, M4 Work et M4 Pro, puis choisissez l’offre adaptée à vos besoins.

Découvrir les offres de Mac dans le cloud