🎈

Playwright で 別タブで Instagram に遷移するテストを書く

2022/08/08に公開

はじめに

前回は、Next.js と microCMS を使ったサイトに Google Analytics を導入し、人気記事ランキングを作成しました。

https://zenn.dev/taka_shino/articles/450d773a99f904

今回は、Playwright を使ってテストを書きます。
具体的には、サイトのヘッダーにある Instagram のアイコンをクリックして正常に Instagram のページに遷移できるかをテストします。

前提

Playwright のインストールと初期設定は終わっているものとします。

テストを書く

別タブで開く

Instagram のアイコンをクリックすると target="_blank" によって、別タブで開くようになっています。
別タブのテストは以下のドキュメントを参考に作成しました。

https://playwright.dev/docs/pages#handling-new-pages

e2e/sample.spec.ts
test('ヘッダーのインスタグラムのアイコンをクリックすると、別タブでインスタグラムのページが開くこと', async ({
  page,
  context,
}) => {
  const [instagramPage] = await Promise.all([
    context.waitForEvent('page'),
    page.locator('[data-test-transition-instagram-button]').click(),
  ])
  await instagramPage.waitForLoadState()
})

Instagram にログインする

別タブで開いた Instagram 以下のように未ログイン状態です。

ここで、ログインに必要な情報をフォームに入力する必要があります。
ユーザー名とパスワードをそれぞれ以下のように指定して入力します。

e2e/sample.spec.ts
test('ヘッダーのインスタグラムのアイコンをクリックすると、別タブでインスタグラムのページが開くこと', async ({
  page,
  context,
}) => {
  const [instagramPage] = await Promise.all([
    context.waitForEvent('page'),
    page.locator('[data-test-transition-instagram-button]').click(),
  ])
  await instagramPage.waitForLoadState()
	
  // ログインに必要な情報をフォームに入力
  await instagramPage.locator('input[name="username"]').fill('sample@test.com')
  await instagramPage.locator('input[name="password"]').fill('password')
})

以下のようにフォームに必要な情報を入力できました。

次にログイン情報を入力した後は、ログインボタンをクリックします。

e2e/sample.spec.ts
test('ヘッダーのインスタグラムのアイコンをクリックすると、別タブでインスタグラムのページが開くこと', async ({
  page,
  context,
}) => {
  const [instagramPage] = await Promise.all([
    context.waitForEvent('page'),
    page.locator('[data-test-transition-instagram-button]').click(),
  ])
  await instagramPage.waitForLoadState()
	
  // ログインに必要な情報をフォームに入力
  await instagramPage.locator('input[name="username"]').fill('sample@test.com')
  await instagramPage.locator('input[name="password"]').fill('password')

  // ログインボタンをクリック
  await instagramPage.locator('button[type="submit"]').click()
})

ログインボタンをクリックすると以下のような画面に遷移します。
ここでは、ログイン情報をブラウザに保存したくないで Not Now をクリックします。

e2e/sample.spec.ts
test('ヘッダーのインスタグラムのアイコンをクリックすると、別タブでインスタグラムのページが開くこと', async ({
  page,
  context,
}) => {
  const [instagramPage] = await Promise.all([
    context.waitForEvent('page'),
    page.locator('[data-test-transition-instagram-button]').click(),
  ])
  await instagramPage.waitForLoadState()
	
  // ログインに必要な情報をフォームに入力
  await instagramPage.locator('input[name="username"]').fill('sample@test.com')
  await instagramPage.locator('input[name="password"]').fill('password')

  // ログインボタンをクリック
  await instagramPage.locator('button[type="submit"]').click()

  // Not Now をクリック
  await instagramPage.locator('text=Not Now').click()

  // ログイン後遷移したページが /hogehoge であること
  await expect(instagramPage).toHaveURL('https://www.instagram.com/hogehoge')
})

ログイン情報を .env ファイルから読み込む

これまでは、ユーザー名とパスワードをテストファイルに書き込んでいましたが、.env ファイルから読み込めるようにします。
以下の記事を参考にさせていただきました。

https://zenn.dev/mimi/scraps/314e19282b7f0b

.env
INSTAGRAM_LOGIN_EMAIL=sample@test.com
INSTAGRAM_LOGIN_PASS=password

.env ファイルに設定した環境変数を使用できるようにします。

e2e/global-setup.ts
import path from 'path'
import { FullConfig } from '@playwright/test'
import dotenv from 'dotenv'

dotenv.config({ path: path.resolve(process.cwd(), '.env') })

async function globalSetup(config: FullConfig) {
  // 略
}

export default globalSetup

playwright.config.tsglobalSetupglobal-setup.ts を指定します。

playwright.config.ts
import { PlaywrightTestConfig, devices } from '@playwright/test'
const PORT = process.env.PORT || 3000
const baseURL = `http://localhost:${PORT}`
const config: PlaywrightTestConfig = {
  globalSetup: require.resolve('./e2e/global-setup.ts'),
  testMatch: '/e2e/**/*.spec.ts',

  use: {
    // 略
  },

  projects: [
    // 略
  ],
}
export default config

.env ファイルに設定した環境変数を使用できるようなったので、以下のようにテストを修正しました。

e2e/sample.spec.ts
test('ヘッダーのインスタグラムのアイコンをクリックすると、別タブでインスタグラムのページが開くこと', async ({
  page,
  context,
}) => {
  const [instagramPage] = await Promise.all([
    context.waitForEvent('page'),
    page.locator('[data-test-transition-instagram-button]').click(),
  ])
  await instagramPage.waitForLoadState()

  // .env ファイルから読み込む
  const { INSTAGRAM_LOGIN_EMAIL, INSTAGRAM_LOGIN_PASS } = process.env
	
  // ログインに必要な情報をフォームに入力
  await instagramPage.locator('input[name="username"]').fill(`${INSTAGRAM_LOGIN_EMAIL}`)
  await instagramPage.locator('input[name="password"]').fill(`${INSTAGRAM_LOGIN_PASS}`)

  // ログインボタンをクリック
  await instagramPage.locator('button[type="submit"]').click()

  // Not Now をクリック
  await instagramPage.locator('text=Not Now').click()

  // ログイン後遷移したページが /hogehoge であること
  await expect(instagramPage).toHaveURL('https://www.instagram.com/hogehoge')
})

おわりに

playwright を使って Instagram のページに遷移できるかテストを書いてみました。
私自身 e2e テストのライブラリをさわったことがなく学びになりました。
まだまだ一部しかテストがない状況ですので、今後もテストを書いていこうと思いました。

今回作成したテストファイルの詳細コード
e2e/sample.spec.ts
import { test, expect } from '@playwright/test'

test.describe('index.tsx', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/')
  })

  test.describe('Header', () => {
    test('ヘッダーのインスタグラムのアイコンをクリックすると、別タブでインスタグラムのページが開くこと', async ({
      page,
      context,
    }) => {
      const [instagramPage] = await Promise.all([
        context.waitForEvent('page'),
        page.locator('[data-test-transition-instagram-button]').click(),
      ])
      await instagramPage.waitForLoadState()
      const { INSTAGRAM_LOGIN_EMAIL, INSTAGRAM_LOGIN_PASS } = process.env
      await instagramPage.locator('input[name="username"]').fill(`${INSTAGRAM_LOGIN_EMAIL}`)
      await instagramPage.locator('input[name="password"]').fill(`${INSTAGRAM_LOGIN_PASS}`)
      await instagramPage.locator('button[type="submit"]').click()
      await instagramPage.locator('text=Not Now').click()
      await expect(instagramPage).toHaveURL('https://www.instagram.com/hogehoge')
    })
  })
  // 他のテスト
}
GitHubで編集を提案

Discussion