-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
はじめてのE2Eテストを作成する #42
Merged
Merged
はじめてのE2Eテストを作成する #42
Changes from 51 commits
Commits
Show all changes
52 commits
Select commit
Hold shift + click to select a range
96010f7
conflict の解消
kazuma-naka 28eff69
.env.local にEMAIL と PASSWORD を設定する手順をREADME に記載する
kazuma-naka 0c04a73
ログインに失敗したときのテストも作成する
kazuma-naka 1342460
script の conflict を解消
kazuma-naka cea11dd
dotenv を devDependencies に移動する
kazuma-naka 144ab6d
package.json を修正する
kazuma-naka 08e520d
npm run e2e で playwright が実行されるように修正する
kazuma-naka 5dcb45d
Login と SignUp ページの pjord.svg の Image 内の height が設定されておらずエラーが起こるバグの修正
kazuma-naka 6e8c23e
playwright を headless モードで実行するように修正する
kazuma-naka cc72100
開発環境の EMAIL と PASSWORD を隠さずにテストファイル内に定義する
kazuma-naka 7edf3c8
npx playwright test のように npx を先頭につける
kazuma-naka bef31f5
CI のテストの修正. npm run test の前に npx playwright intall を実行する
kazuma-naka a97a415
test CI が通るようにテスト前に supabase, Next.js を起動する
kazuma-naka ab8a0a5
Playwright の公式ページを参考にテストの WorkFlow を修正
kazuma-naka 4c6c4b7
test CI が通るようにテスト前に supabase, Next.js を起動する
kazuma-naka 7eee630
test CI が通るようにテスト前に supabase, Next.js を起動する. Next.js が起動したら次の処理に移行する
kazuma-naka eac3386
npx wait-on localhost:3000 を削除する
kazuma-naka eb0d2e6
playwright.config の webServer のアンコメントを取り除く
kazuma-naka 501ce1f
playwright を起動する際に Next.js をビルドしないとエラーが出るので Next.js をe2e テスト前にビルドするように修正
kazuma-naka 6900b45
dotenv cli をインストールして supabase のURL と Anon Key をテスト時に読み込む
kazuma-naka da86d06
next build 時に .env を CI 環境で読み込むように修正
kazuma-naka ef14fc4
.env.local はリモートに含まれないため dotenv-cli を依存性から外す
kazuma-naka 41a0126
ci.yml の test 内で Next.js をビルドするために .env.local を動的に作成する
kazuma-naka 825d720
ci.yml の npm run start をバックグラウンドで実行する
kazuma-naka 511ab84
seed.test.sql を作成してテスト環境のDBを構築する
kazuma-naka 88678fd
seed.test.sql の path を設定する
kazuma-naka 5a155a7
seed.test.sql の path を変更する
kazuma-naka 9269167
seed.test.sql のタイポを修正
kazuma-naka ab67c7b
E2E テスト後に DB をリセットする
kazuma-naka ea65df4
E2E テスト後の処理のタイポを修正
kazuma-naka b5246d0
ci.yml のテーブルの一括削除の記述を消す
kazuma-naka a85d06e
global.setup.ts でテスト用のユーザーをサインアップして新規登録する
kazuma-naka d6cf2e8
[email protected] のユーザーをテストのために新規作成、テスト後に削除する
kazuma-naka b451d4f
service role key を ci のテスト環境でも.env.local に追加する
kazuma-naka 9b8d07c
.env.local の変数 NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY に名前を変更する
kazuma-naka c0f43c9
ci.yml NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEYに修正
kazuma-naka 527a40d
テスト用ユーザーの作成の実装をやめて元に戻す
kazuma-naka 3e79739
E2E テスト用の DB のコンテナを別に用意する
kazuma-naka 25ce5fb
setup.ts, teardown.ts playwright の設定を削除
kazuma-naka b285068
e2e 用の supabase の環境をローカルに構築する
kazuma-naka a9870f2
supabase を clone してローカルに構築する
kazuma-naka 980cd0d
Supabase を git clone でローカル環境に構築することをキャンセルする
kazuma-naka 3c248c2
supawright を使ってE2Eテストを実装する
kazuma-naka 26f99ba
Supawright を追加
kazuma-naka 1b7114b
Supawright をつかってテスト前にユーザーを作成する。Supawright は自動的にテスト内で作成されたテーブル、ユーザーを削除
kazuma-naka 43a43d8
e2e テストとコンポネントテストを npm run test で両方とも実行するようにする
kazuma-naka 7857c23
.env.test ファイルを削除
kazuma-naka 52ede0c
不必要なものを .gitignore から削除する
kazuma-naka bd8ccc5
dotenv-cli を削除する
kazuma-naka 04e64f5
supawright の createUser() で email を自動的に生成してくれるので生成された email を使用する
kazuma-naka e488be3
ci.yml の不必要な変数を削除
kazuma-naka 02feb22
モデルの2重管理を解消
kazuma-naka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
export type Json = | ||
| string | ||
| number | ||
| boolean | ||
| null | ||
| { [key: string]: Json | undefined } | ||
| Json[] | ||
|
||
export type Database = { | ||
graphql_public: { | ||
Tables: { | ||
[_ in never]: never | ||
} | ||
Views: { | ||
[_ in never]: never | ||
} | ||
Functions: { | ||
graphql: { | ||
Args: { | ||
operationName?: string | ||
query?: string | ||
variables?: Json | ||
extensions?: Json | ||
} | ||
Returns: Json | ||
} | ||
} | ||
Enums: { | ||
[_ in never]: never | ||
} | ||
CompositeTypes: { | ||
[_ in never]: never | ||
} | ||
} | ||
public: { | ||
Tables: { | ||
companies: { | ||
Row: { | ||
created_at: string | ||
id: number | ||
memo: string | null | ||
name: string | ||
website: string | null | ||
} | ||
Insert: { | ||
created_at?: string | ||
id?: number | ||
memo?: string | null | ||
name: string | ||
website?: string | null | ||
} | ||
Update: { | ||
created_at?: string | ||
id?: number | ||
memo?: string | null | ||
name?: string | ||
website?: string | null | ||
} | ||
Relationships: [] | ||
} | ||
users: { | ||
Row: { | ||
date_of_birth: string | null | ||
email: string | ||
first_name: string | null | ||
first_name_kana: string | null | ||
id: string | ||
last_name: string | null | ||
last_name_kana: string | null | ||
role: string | null | ||
} | ||
Insert: { | ||
date_of_birth?: string | null | ||
email: string | ||
first_name?: string | null | ||
first_name_kana?: string | null | ||
id: string | ||
last_name?: string | null | ||
last_name_kana?: string | null | ||
role?: string | null | ||
} | ||
Update: { | ||
date_of_birth?: string | null | ||
email?: string | ||
first_name?: string | null | ||
first_name_kana?: string | null | ||
id?: string | ||
last_name?: string | null | ||
last_name_kana?: string | null | ||
role?: string | null | ||
} | ||
Relationships: [] | ||
} | ||
} | ||
Views: { | ||
[_ in never]: never | ||
} | ||
Functions: { | ||
[_ in never]: never | ||
} | ||
Enums: { | ||
[_ in never]: never | ||
} | ||
CompositeTypes: { | ||
[_ in never]: never | ||
} | ||
} | ||
} | ||
|
||
type PublicSchema = Database[Extract<keyof Database, "public">] | ||
|
||
export type Tables< | ||
PublicTableNameOrOptions extends | ||
| keyof (PublicSchema["Tables"] & PublicSchema["Views"]) | ||
| { schema: keyof Database }, | ||
TableName extends PublicTableNameOrOptions extends { schema: keyof Database } | ||
? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] & | ||
Database[PublicTableNameOrOptions["schema"]]["Views"]) | ||
: never = never, | ||
> = PublicTableNameOrOptions extends { schema: keyof Database } | ||
? (Database[PublicTableNameOrOptions["schema"]]["Tables"] & | ||
Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends { | ||
Row: infer R | ||
} | ||
? R | ||
: never | ||
: PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] & | ||
PublicSchema["Views"]) | ||
? (PublicSchema["Tables"] & | ||
PublicSchema["Views"])[PublicTableNameOrOptions] extends { | ||
Row: infer R | ||
} | ||
? R | ||
: never | ||
: never | ||
|
||
export type TablesInsert< | ||
PublicTableNameOrOptions extends | ||
| keyof PublicSchema["Tables"] | ||
| { schema: keyof Database }, | ||
TableName extends PublicTableNameOrOptions extends { schema: keyof Database } | ||
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] | ||
: never = never, | ||
> = PublicTableNameOrOptions extends { schema: keyof Database } | ||
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { | ||
Insert: infer I | ||
} | ||
? I | ||
: never | ||
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"] | ||
? PublicSchema["Tables"][PublicTableNameOrOptions] extends { | ||
Insert: infer I | ||
} | ||
? I | ||
: never | ||
: never | ||
|
||
export type TablesUpdate< | ||
PublicTableNameOrOptions extends | ||
| keyof PublicSchema["Tables"] | ||
| { schema: keyof Database }, | ||
TableName extends PublicTableNameOrOptions extends { schema: keyof Database } | ||
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] | ||
: never = never, | ||
> = PublicTableNameOrOptions extends { schema: keyof Database } | ||
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { | ||
Update: infer U | ||
} | ||
? U | ||
: never | ||
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"] | ||
? PublicSchema["Tables"][PublicTableNameOrOptions] extends { | ||
Update: infer U | ||
} | ||
? U | ||
: never | ||
: never | ||
|
||
export type Enums< | ||
PublicEnumNameOrOptions extends | ||
| keyof PublicSchema["Enums"] | ||
| { schema: keyof Database }, | ||
EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } | ||
? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"] | ||
: never = never, | ||
> = PublicEnumNameOrOptions extends { schema: keyof Database } | ||
? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName] | ||
: PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] | ||
? PublicSchema["Enums"][PublicEnumNameOrOptions] | ||
: never | ||
|
||
export type CompositeTypes< | ||
PublicCompositeTypeNameOrOptions extends | ||
| keyof PublicSchema["CompositeTypes"] | ||
| { schema: keyof Database }, | ||
CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { | ||
schema: keyof Database | ||
} | ||
? keyof Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"] | ||
: never = never, | ||
> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database } | ||
? Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] | ||
: PublicCompositeTypeNameOrOptions extends keyof PublicSchema["CompositeTypes"] | ||
? PublicSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] | ||
: never | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { describe } from "node:test"; | ||
import { expect } from "@playwright/test"; | ||
import { withSupawright } from "supawright"; | ||
import type { Database } from "./database.types"; | ||
|
||
const test = withSupawright<Database, "public">(["public"]); | ||
|
||
describe("Login and Logout E2E test", () => { | ||
let validEmail: string | undefined; | ||
const e2ePassword = "e2e_password"; | ||
|
||
test.beforeEach(async ({ supawright }) => { | ||
const attributes = { | ||
password: e2ePassword, | ||
email_confirm: true, | ||
}; | ||
const user = await supawright.createUser(attributes); | ||
validEmail = user.email; | ||
}); | ||
|
||
test("Should Success Login with valid Email and Password then Logout", async ({ | ||
page, | ||
}) => { | ||
await page.goto("http://localhost:3000/"); | ||
await page.getByRole("link", { name: "ログイン" }).click(); | ||
|
||
console.log(`valid email: ${validEmail}`); | ||
|
||
await page.getByPlaceholder("[email protected]").fill(validEmail ?? ""); | ||
await page.getByLabel("Password").fill(e2ePassword); | ||
await page.getByRole("button", { name: "ログイン" }).click(); | ||
|
||
const logoutButton = page.getByRole("link", { name: "ログアウト" }); | ||
await expect(logoutButton).toBeVisible(); | ||
|
||
/** 現在リロードしないと画面が更新されずログイン、サインインが表示されない **/ | ||
await logoutButton.click(); | ||
await page.waitForTimeout(1500); | ||
|
||
await page.reload(); | ||
|
||
const loginButton = page.getByRole("link", { name: "ログイン" }); | ||
const signInButton = page.getByRole("link", { name: "ユーザー登録" }); | ||
|
||
await expect(loginButton).toBeVisible(); | ||
await expect(signInButton).toBeVisible(); | ||
}); | ||
|
||
test("Should Fail Login with Invalid Email and Password", async ({ | ||
page, | ||
}) => { | ||
await page.goto("http://localhost:3000/"); | ||
await page.getByRole("link", { name: "ログイン" }).click(); | ||
|
||
await page.getByPlaceholder("[email protected]").fill("[email protected]"); | ||
await page.getByLabel("Password").fill("invalidpassword"); | ||
await page.getByRole("button", { name: "ログイン" }).click(); | ||
|
||
const loginButton = page.getByRole("button", { name: "ログイン" }); | ||
await expect(loginButton).toBeVisible(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: モデルが二重管理になっていますが、このファイルって必要でしょうか?
src/lib/database.types をimportしてもテストは動作していそうです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/libのほうをimportすると
Type 'Database' does not satisfy the constraint 'GenericDatabase'.
というエラーになるんですが、もしかして型定義が古いためですか? このE2Eのほうをsrc/lib/の方で使えばよさそうThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
レビューありがとうございます😊
Supawright を使用するために Supabase の型のタイプを変更する必要がありました。
src/lib/databaase.types.ts に変更しました。
https://github.com/isaacharrisholt/supawright#:~:text=%2D%20export%20interface%20Database%20%7B%0A%2B%20export%20type%20Database%20%3D%20%7B