動かざることバグの如し

近づきたいよ 君の理想に

Puppeteerでリダイレクト元URLとリダイレクト先URLを取得する方法

環境

  • puppeteer 1.12
  • nodejs 10

やりたいこと

Puppeteerでリダイレクトを記録したい

コード

すでにいろいろ記事は上がっているが、以下。ポイントはredirectChain()使うところだろうか。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  const response = await page.goto('https://httpbin.org/redirect/3');
  for(const req of response.request().redirectChain()) {
    console.log(`${req.url()} => ${req.response().headers().location}`);
  }
  await browser.close();
})();

reqはRequestクラス。req.url()でリダイレクト元、req.response().headers().locationでリダイレクト先を取得できる。リダイレクト先はもっといい取得方法がありそうだけど、わかっていない、、、

実行すると以下のようになる。

$node red.js 
https://httpbin.org/redirect/3 => /relative-redirect/2
https://httpbin.org/relative-redirect/2 => /relative-redirect/1
https://httpbin.org/relative-redirect/1 => /get

当然絶対URLで書いても大丈夫 。https://httpbin.org/absolute-redirect/3 とかだと

$node red.js 
https://httpbin.org/absolute-redirect/3 => http://httpbin.org/absolute-redirect/2
http://httpbin.org/absolute-redirect/2 => http://httpbin.org/absolute-redirect/1
http://httpbin.org/absolute-redirect/1 => http://httpbin.org/get

なお、RequestInterceptionの監視による記録もできるが、単に一連のリダイレクトを記録したいならredirectChain()使ったほうが良さげ。

await page.setRequestInterception(true);
page.on('request', request => {
  if (request.isNavigationRequest() && request.redirectChain().length) {
    console.log(request.url());
  }
  request.continue();      
});

RspecでリモートIPアドレスを偽装してテストする

環境

やりたいこと

IP制限のテストがしたくなった。が、当然request.remote_ipはローカルでテストしている以上ずっと「127.0.0.1」のまま。

外部にデプロイしてそこでテスト〜なんて当たり前だができないので、なんとか別のIPアドレスを振る舞えないか調べてたらあった。

allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return('8.8.8.8')

これで8.8.8.8からのアクセスのようになる。

なんかもっといい方法ありそうだけど。。

Rspecの親

まずはこれ見ろ

インストール

構文わからん

きれいに書きたい

RSpecで現在時刻を変更してテストしたいときはtravel_toが便利

環境

やりたいこと

RSpecでいろいろテストを書いているのだが、日時が絡むテストが非常に面倒である。例えば一定時間経つと挙動が変わるとか、〜年より前、後で振る舞いが変わるテスト、など。

が、さすがRails、travel_toというヘルパーメソッドがあった。

何ができるのかというと、現在時刻を偽装できる、つまりタイムトラベル。。。!

使い方

デフォルトでは使えないのでインクルードする。rails_helper.rbに以下追記

RSpec.configure do |config|
  config.include ActiveSupport::Testing::TimeHelpers
end

で、以下のように使える。

require 'rails_helper'

RSpec.describe User, type: :model do

  describe "2015年の時" do
    it "2015年になっていること" do
      travel_to Date.new(2015,1,1) do
        expect(Date.current).to eq '2015-01-01'.to_date
      end
    end
  end
end

実はブロックで区切らなくてもit抜けた時点でトラベルから戻ってこれる(現在時刻になる)

  describe "2015年の時" do
    it "2015年になっていること" do
      travel_to Date.new(2016,1,1)
      expect(Date.current).to eq '2016-01-01'.to_date
    end
  end

  describe "30分後のとき" do
    it "30分後になっていること" do
      now1 = Time.now
      travel_to 30.minutes.after do
        now2 = Time.now
        expect(now2-now1 >= 30).to eq true
      end
    end
  end

end

仕組み

ソースコード追おうと思ったけど先人の方がいらっしゃったのでリンクだけ(

参考リンク

見てるとrails4.1以降で使えるようなので、どのRailsでも使えるという認識でいいのでは