import { chromium } from 'playwright'; import { mkdirSync } from 'fs'; const screenshotDir = 'C:/tmp/playwright_screenshots'; mkdirSync(screenshotDir, { recursive: true }); const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: 1400, height: 900 } }); const page = await context.newPage(); async function screenshot(name) { const path = `${screenshotDir}/${name}.png`; await page.screenshot({ path, fullPage: false }); console.log(` [Screenshot: ${name}.png]`); } // Login await page.goto('http://localhost:3000/fertilizer/new'); await page.waitForLoadState('networkidle'); if (page.url().includes('/login')) { await page.fill('#username', 'akira'); await page.fill('input[type="password"]', 'keina2025'); await page.click('button[type="submit"]'); await page.waitForNavigation({ timeout: 10000 }).catch(() => {}); await page.waitForLoadState('networkidle'); await page.goto('http://localhost:3000/fertilizer/new'); await page.waitForLoadState('networkidle'); } // Step 3: Select にこまる console.log('\n=== Step 3: Select 品種 "にこまる" ==='); const selects = await page.locator('select').all(); await selects[1].selectOption({ label: 'にこまる' }); await page.waitForTimeout(1500); await screenshot('step3_nikkomaru_selected'); console.log('Selected にこまる - 15 fields auto-added'); // Step 4: Click + 肥料を追加 button console.log('\n=== Step 4: Click "+ 肥料を追加" ==='); const addBtn = page.locator('button').filter({ hasText: '肥料を追加' }).first(); await addBtn.click(); await page.waitForTimeout(500); // Modal appeared - click グアノ console.log(' Modal open - clicking グアノ...'); const guanoItem = page.locator('text=グアノ').first(); await guanoItem.click(); await page.waitForTimeout(1500); await screenshot('step4_guano_added'); // Check what appeared on the page const pageText = await page.locator('body').textContent(); const cleanText = pageText?.replace(/\s+/g, ' '); const relevantPart = cleanText?.match(/自動計算設定.{0,500}/)?.[0] || cleanText?.substring(0, 600); console.log('After グアノ added:', relevantPart); // Find the param input for グアノ console.log('\n=== Checking fertilizer section structure ==='); const fertSection = page.locator('[class*="fertilizer"], [class*="Fertilizer"]').first(); const fertHTML = await page.locator('body').innerHTML(); // Look for the input near グアノ const inputs = await page.locator('input[type="number"], input[type="text"]').all(); console.log('Number of inputs:', inputs.length); for (let i = 0; i < inputs.length; i++) { const val = await inputs[i].inputValue(); const placeholder = await inputs[i].getAttribute('placeholder'); const type = await inputs[i].getAttribute('type'); console.log(` Input[${i}]: value="${val}", placeholder="${placeholder}", type="${type}"`); } // Look for 計算 button const calcButton = page.locator('button').filter({ hasText: '計算' }); const calcVisible = await calcButton.isVisible(); console.log('計算 button visible:', calcVisible); await browser.close();