Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion e2e/calendar-integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ test("user can connect and disconnect various calendars on the calendar connect
await loginPwInput.fill("Test1234!");

await page.getByRole("button", { name: "로그인" }).click();
await page.waitForURL("**/schedule/create", { timeout: 60000 });
await page.waitForURL("**/dashboard", { timeout: 60000 });

// 4. 캘린더 연동 페이지 이동
await page.goto("/calendar/connect");
Expand Down
3 changes: 2 additions & 1 deletion e2e/host-flow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ test("host can create a schedule and receive safe participant and host links", a
await page.getByRole("button", { name: "로그인" }).click();

// 3. 스케줄 생성
await page.waitForURL("**/schedule/create", { timeout: 60000 });
await page.waitForURL("**/dashboard", { timeout: 60000 });
await page.goto("/schedule/create");
Comment on lines +81 to +82

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# /dashboard 페이지 구현 확인: 자동 리다이렉트 로직 유무, 비동기 데이터 페칭 여부
ast-grep --pattern $'export default function $_($$) {
  $$$
  redirect($$$)
  $$$
}' src/app/dashboard

# useEffect 내 네비게이션 로직 검색
rg -nP --type=tsx -C3 'useRouter|redirect|window\.location' src/app/dashboard

Repository: Siul49/moim

Length of output: 83


🏁 Script executed:

# dashboard 페이지 위치 확인
fd -e ts -e tsx "dashboard" src/app/

Repository: Siul49/moim

Length of output: 37


🏁 Script executed:

# dashboard 페이지 리다이렉트/네비게이션 로직 검색 (타입 지정 수정)
rg -nP --type ts,tsx -C3 'useRouter|redirect|window\.location' src/app/

Repository: Siul49/moim

Length of output: 86


🏁 Script executed:

# host-flow.spec.ts 전체 L75-90 구간 확인
sed -n '75,90p' e2e/host-flow.spec.ts

Repository: Siul49/moim

Length of output: 612


🏁 Script executed:

# dashboard 페이지 구현 전체 확인 (ast-grep 대신 rg로 export default 검색)
rg -A 20 'export default function|export const.*dashboard' src/app/dashboard --type ts,tsx

Repository: Siul49/moim

Length of output: 86


🏁 Script executed:

# dashboard 페이지 파일 확인 (경로 재검색)
find src/app -type d -name "dashboard"

Repository: Siul49/moim

Length of output: 73


🏁 Script executed:

# dashboard 관련 모든 파일 검색
find src -name "*dashboard*"

Repository: Siul49/moim

Length of output: 73


🏁 Script executed:

# (auth) 이후 로그인 후 이동 페이지 확인 - app 구조 조회
find src/app -type f \( -name "page.tsx" -o -name "layout.tsx" \) | head -20

Repository: Siul49/moim

Length of output: 591


🏁 Script executed:

# host-flow.spec.ts 전체 코드 읽기 (파일 크기 확인 후)
wc -l e2e/host-flow.spec.ts

Repository: Siul49/moim

Length of output: 81


🏁 Script executed:

# dashboard/page.tsx 구현 확인
cat src/app/dashboard/page.tsx

Repository: Siul49/moim

Length of output: 734


🏁 Script executed:

# host-flow.spec.ts 전체 코드 읽기 (127줄)
cat e2e/host-flow.spec.ts

Repository: Siul49/moim

Length of output: 4420


/dashboard 대기 후 바로 네비게이션 — 현 코드는 안전하나 방어적 로드 확인 추가 권장.

L81-82의 패턴 자체는 안전합니다. dashboard/page.tsx는 리다이렉트 로직 없는 서버 컴포넌트이고, waitForURL 완료는 리다이렉트 및 페이지 로드 시작을 의미하므로 L82의 goto와 충돌하지 않습니다. 다만 L83의 waitFor 앞에 명시적 로드 상태 확인을 추가하면 더욱 견고합니다.

Why: E2E 테스트 안정성 및 Playwright 모범 사례 (네트워크 유휴 상태 보장)
How: 페이지 요소 대기 전에 로드 완료 확인

 await page.waitForURL("**/dashboard", { timeout: 60000 });
 await page.goto("/schedule/create");
+
 const titleInput = page.getByLabel("모임 제목");
-await titleInput.waitFor({ state: "visible", timeout: 15000 });
+await page.waitForLoadState("networkidle");
+await titleInput.waitFor({ state: "visible", timeout: 15000 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/host-flow.spec.ts` around lines 81 - 82, The code at lines 81-82 is safe,
but add a defensive load state verification before the waitFor call on line 83
to follow Playwright best practices. After the page.goto call at line 82 and
before the waitFor for page elements, insert a page.waitForLoadState call (such
as 'networkidle' or 'domcontentloaded') to ensure the page has fully loaded and
the network is idle before attempting to wait for and interact with page
elements. This improves E2E test stability and reliability.


const titleInput = page.getByLabel("모임 제목");
await titleInput.waitFor({ state: "visible", timeout: 15000 });
Expand Down
40 changes: 9 additions & 31 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function LoginPage() {
// Webkit/Safari 쿠키 디스크 동기화 대기 시간 부여
await new Promise((resolve) => setTimeout(resolve, 2000));

let redirectUrl = "/schedule/create";
let redirectUrl = "/dashboard";
if (typeof window !== "undefined") {
const params = new URLSearchParams(window.location.search);
const next = params.get("redirect") ?? params.get("next");
Expand All @@ -67,7 +67,7 @@ export default function LoginPage() {

const handleOAuthLogin = async (provider: "google" | "kakao" | "apple") => {
const supabase = createClient();
let next = "/schedule/create";
let next = "/dashboard";
if (typeof window !== "undefined") {
const params = new URLSearchParams(window.location.search);
const nextParam = params.get("redirect") ?? params.get("next");
Expand Down
2 changes: 1 addition & 1 deletion src/app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ function SocialButton({
}) {
const handleOAuthLogin = async (provider: "google" | "kakao" | "apple") => {
const supabase = createClient();
let next = "/schedule/create";
let next = "/dashboard";
if (typeof window !== "undefined") {
const params = new URLSearchParams(window.location.search);
const nextParam = params.get("redirect") ?? params.get("next");
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/auth/naver/callback/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { createAdminClient } from "@/lib/supabase/admin";

export const dynamic = "force-dynamic";
const ADDITIONAL_INFO_REDIRECT = "/signup/additional-info?provider=naver";
const LOGIN_SUCCESS_REDIRECT = "/schedule/create";
const LOGIN_SUCCESS_REDIRECT = "/dashboard";
const LOGIN_FAILURE_REDIRECT = "/login?error=naver_login_failed";

/**
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/naver/callback/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export async function GET(req: NextRequest) {
const identifier = profile.email ?? profile.nickname ?? profile.id;

return NextResponse.redirect(
`${baseUrl}/schedule/create?connected=naver&user=${encodeURIComponent(identifier)}`,
`${baseUrl}/dashboard?connected=naver&user=${encodeURIComponent(identifier)}`,
);
} catch (err) {
console.error("[naver.callback] 오류:", err);
Expand Down