簡體   English   中英

Testcafe 從域中獲取所有 Cookie,將它們存儲在 Object / Array 中並檢查 Cookie 的名稱是否在數組中

[英]Testcafe Getting all Cookies from domain, store them in Object / Array and check if the Names of the Cookies are in an Array

我是 Testcafé 的新手,需要從網站獲取所有 Cookie,將它們存儲在對象或數組中,然后查看 Cookie 的名稱是否與字符串數組匹配,以查看是否設置了一些 Cookie; 這需要在 Typescript 中完成; 在純 Javascript 中會更容易,但這些是要求。

為了實現這一點,我實現了一個接口,其中包含我需要從 Cookie 中獲得的所有屬性:

class CookieInterface {
    static getName: string;

    constructor(domain: string, name: string, expirationDate: bigint,hostOnly: boolean, httpOnly: boolean,
                path: string, sameSite: string, secure: boolean, session: boolean, storeId: number,value: bigint,
                id: number) {
        this.domain = domain;
        this.expirationDate = expirationDate;
        this.hostOnly = hostOnly;
        this.httpOnly = httpOnly;
        this.path = path;
        this.sameSite = sameSite;
        this.secure = secure;
        this.session = session;
        this.name = name,
        this.storeId = storeId,
        this.value = value,
        this.id = id
    }

    domain: string
    expirationDate: bigint
    hostOnly: boolean
    httpOnly: boolean
    name: string
    path: string
    sameSite: string
    secure: boolean
    session: boolean
    storeId: number
    value: bigint
    id: number

    getName(cookieName: string){
     
    }
}

export {
    CookieInterface
};

這是我到目前為止提出的測試用例的實現:

import 'testcafe';
import consentLayer from '../../page-objects/consent-layer';
import {ClientFunction, Selector} from 'testcafe';
import {CookieInterface} from './cookieInterface';

fixture('Cookie Checker')
    .page('http://www.mywebsite.com')
    .beforeEach(async t => {
        await t.setTestSpeed(0.1)
        await t.maximizeWindow()
    })

test
    .disablePageCaching
    .timeouts({
        pageLoadTimeout:    1000,
        pageRequestTimeout: 1000
    })
    ('should check if all relevant Cookies are set', async t => {

        let getCookies = ClientFunction(() => ()

TODO:實現一個獲取所有 Cookie 或使用接口並將屬性名稱與字符串數組進行比較的函數)

        let getCookieName = CookieInterface.getName;

        await t.wait(3000);
        await t.navigateTo('http://www.mywebsite.com')
        const cookies1 = await getCookies();
        await t.expect(cookies1.length).gt(
            0
        )

        await t.switchToIframe(Selector('*[id^=sp_message_iframe_]'));
        await t.expect(Selector('button[title="Accept all"]').exists).ok();
        await t.switchToMainWindow();
        await consentLayer.clickAcceptButton();
        await t.eval(() => location.reload(true))
        const cookies2 = await getCookies();
        await t.expect(cookies2.length).gt(
            0
        )
        await t.expect(Selector('*[id^=sp_message_iframe_]').exists).notOk();
        await t.expect(Selector('button[title="Accept All"]').exists).notOk();
    });

這是我目前被困住的情況,因此希望得到任何提示或幫助,尤其是關於如何從所有 Cookie 中獲取名稱並將它們與字符串數組進行比較的方法; 提前致謝!

TestCafe 不提供獲取帶有元數據的 cookie 的標准方法。 作為此問題的一部分,我們正在研究接收 cookie 的機制。

最簡單的方法如下:

const getCookie = ClientFunction(() => document.cookie);

但是,它只會返回name=value對。

以下是一些解決方法:

使用cookieStore
const getCookie = ClientFunction(() => cookieStore.getAll());

在這種情況下,必須使用--hostname localhost標志啟動 TestCafe,並使用--allow-insecure-localhost標志啟動 Chrome。 所以運行命令可能如下所示: testcafe "chrome: --allow-insecure-localhost" --hostname localhost test.js這種方法有兩個缺點:

  1. 由於代理,您收到的某些對象字段將無效。
  2. 將來,cookieStore 函數返回的值可能會發生變化。
直接從文件系統讀取cookies:

在 Windows 中,Chrome 將 cookie 存儲在一個文件中: C:\Users\<User>\AppData\Local\Google\Chrome\User Data\Default\Cookies 這種方法有以下缺點:

  1. 在每個操作系統中,每個瀏覽器都有自己的文件路徑。
  2. 很難理解數據存儲格式。
  3. 只有當客戶端在同一台計算機上運行時,您才能訪問文件系統(不可能遠程運行測試)。
攔截cookies:
import { Selector, ClientFunction } from 'testcafe';

fixture `About`
    .page`about:blank`;

test('cookie hook test', async t => {
    const setCookie = ClientFunction(string => document.cookie = string);
    const getCookie = ClientFunction(() => document.cookie);

    const name    = 'foo';
    const value   = 'bar';
    const expires = Date.now() - Date.now() % 1000 + 60000;

    await setCookie(`${name}=${value}; expires=${(new Date(expires)).toUTCString()}`);

    const cookie = await getCookie();

    await t.expect(cookie).eql({ [name]: { name, value, expires } });
})
    .before(async t => {
        const setCookieHooks = ClientFunction(() => {
            const cookie = {};

            document.__defineGetter__('cookie', () => cookie);
            document.__defineSetter__('cookie', raw => {
                const pairs  = raw.split(';').filter(string => !!string).map(string => string.trim().split('='));

                const [name, value] = pairs.shift();

                const result = { name, value };

                pairs.forEach(([key, val]) => result[key] = val);

                result.expires = result.expires ? Date.parse(result.expires) : null;

                cookie[name] = result;
            });
        });

        await setCookieHooks();
    });

自 TestCafe 1.19.0 版本以來,無需發明復雜的解決方法來與瀏覽器 cookie 交互。 我們的 cookie 管理 API 提供了一種靈活且跨瀏覽器的方式來設置、獲取或刪除頁面 cookie,即使是那些具有HttpOnly屬性的頁面 cookie。 發行說明中閱讀更多信息。

以下示例顯示了使用 cookie 的常見情況。

fixture`Cookies API`;
 
test('get/set cookie test', async t => {
   const name  = 'foo';
   const value = 'bar';
 
   var expires = new Date();
   expires.setDate(expires.getDate() + 3); //cookies for 3 days
 
   await t.setCookies({
       name,
       value,
       expires
   });
 
   const cookies = await t.getCookies();
 
   await t.expect(cookies[0]).contains({ name, value, expires });
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM