89393


今作っているフロントエンドのアプリケーションが、(JST)時刻に依存した挙動をします。

このアプリの、夜の時の挙動を確認したいと思っているのですが、ブラウザ上でこれを確かめる方法はありますか? なんとなく、 PC
の時刻自体をズラしてやれば、おそらくイケる気がするのですが、そこまでやるのはいろいろ大袈裟だと思い、特に例えば devtools
の機構などで、時刻を一時的に手動で設定できるようなものがあれば良いな、と思い質問しています。

少し検索してみた結果、 timezone の変更方法は hit するものの、時刻自体を変更する方法が見あたらなかったのでの質問です。

ブラウザとしては、 firefox もしくは chrome で実現する方法を探しています。

## 追記

> Date オブジェクトのメソッドをオーバーライドするといった方法では不十分（あるいはもっと容易な方法が好ましい）でしょうか？

本番環境でしか再現しない挙動があり、その確認を行いたいがために、ブラウザの時刻を変更したい、と思っている状態です。


CC BY-SA 4.0
2022-06-14T02:23:24.097
89380
2022-06-16T21:45:44.353
2022-06-16T21:45:44.353
3054
754
question
javascript google-chrome テスト firefox google-chrome-devtools
テスト目的で、ブラウザの時刻を一時的に夜(e.g. 深夜0時) にできますか?


### libfaketime

oriri さんのコメントで出ている [libfaketime](https://github.com/wolfcw/libfaketime) を
Linux
で試したところ、概ね動いているようなので、これが簡単でよいのではないでしょうか。ファイルのタイムスタンプなどもずれると思うので、メインのブラウザでは動かさない方がよいかも知れません。

[code]

    # 最新バージョンにはコマンドが付属しています
    
    # google-chrome などは問題なく動いているようです
    faketime '00:00' google-chrome
    
    # firefox は --exclude-monotonic なしだと描画のタイミングがおかしく、使えません
    faketime --exclude-monotonic '00:00' firefox
    
[/code]

### モック

これもコメントで出ている方法ですが、JavaScript の関連 API
をデバッグ用のモックに入れ替える手順を簡単に書いておきます。ある程度は対象サイトの構成を理解しておく必要があります。下のコードが必ず動くわけではないです。例えば
Web Worker や 動的に生成される iframe などは考慮していません。

#### 読み込ませる JavaScript の作成

モックライブラリのインストール: [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-
timers) を使うことにします。Jest で使われているものです。

[code]

    npm install @sinonjs/fake-timers
    
[/code]

モックを読み込むコード: `MOCK.mjs`

[code]

    import FakeTimers from "@sinonjs/fake-timers"
    
    console.log("FakeTimers インストール前:", Date())
    let clock = FakeTimers.install({
        // 時間を自動で進める
        shouldAdvanceTime: true,
    })
    // 深夜に設定
    clock.setSystemTime(Date.parse("2022-01-01T00:00+09:00"))
    console.log("FakeTimers インストール後:", Date())
    
    export {FakeTimers, clock}
    
[/code]

ビルド: 出力は `dist/MOCK.js`

[code]

    parcel build --global MOCK --no-source-maps --no-minify MOCK.mjs
    
[/code]

これで出来た `dist/MOCK.js` を対象サイトに読み込ませます。ブラウザのコンソールでは、グローバル変数 `MOCK` を通じて `fake-
timers` の API にアクセスできます。

#### ブラウザを操作する場合

デバック対象のスクリプトが読まれる前にモックのコードを実行できれば何でもよいです。ブラウザ拡張や、いわゆるユーザースクリプトなどでも出来るかも知れません。下は
Puppeteer を使っています。

Puppeteer のインストール:

[code]

    npm install puppeteer
    
[/code]

コード: `page_with_mock.mjs`

[code]

    import puppeteer from "puppeteer"
    import fs from "fs"
    
    async function openPageWithCode(url, code) {
        const browser = await puppeteer.launch({
            headless: false,
        })
        const page = await browser.newPage()
        await page.evaluateOnNewDocument(code)
        await page.goto(url)
    }
    
    const code = fs.readFileSync("dist/MOCK.js", "utf8")
    const url = "https://google.com/"
    await openPageWithCode(url, code)
    
[/code]

ここで操作した `page` でしかモックは読み込まれません。

実行:

[code]

    node page_with_mock.mjs
    
[/code]

#### プロキシを使う場合

デバック対象のスクリプトが読まれる前にモックが読まれるように、レスポンスを改変すればよいです。例えば
[mitmproxy](https://mitmproxy.org/) を使う場合、このようになります。乱暴ですが `<head>` の後に
`script` タグを追加しています。

[code]

    mitmdump \
        --map-local ':MOCK\.js:dist/MOCK.js' \
        --modify-body ':~s ~t "text/html":<head>:<head><script src="MOCK.js"></script>'
    
[/code]


CC BY-SA 4.0
2022-06-15T04:20:31.813
89393
2022-06-15T04:41:10.267
2022-06-15T04:41:10.267
3054
3054
89380
answer