如何使用PHP语法在Codeception中从Datepicker选择自定义日期
Hey there! I’ve tackled this exact scenario multiple times with Codeception and Selenium, so let’s break down the two main approaches to handle custom date selection—depending on how your datepicker is built.
Approach 1: Direct Input (If the Datepicker Allows It)
Many datepickers are tied to a standard text input that accepts direct date entry (even if it looks like a fancy calendar). This is the simplest method:
// In your Cest or AcceptanceTester class public function selectCustomDate(AcceptanceTester $I) { // Replace with your date input's CSS selector and target date (use a format the input accepts) $I->fillField('#booking-date', '2024-06-15'); // Optional: Trigger a change event to ensure the page recognizes the input $I->executeJS('document.querySelector("#booking-date").dispatchEvent(new Event("change"));'); }
Pro tip: Always check if the input is readonly first—if it is, you’ll need to use the calendar interaction method below.
Approach 2: Interact with the Datepicker Calendar
If you have to click through the calendar UI (e.g., the input is readonly or the app enforces calendar selection), follow these steps:
Step 1: Trigger the Datepicker Popup
First, click the element that opens the calendar (could be the input itself or a separate icon):
$I->click('#datepicker-icon'); // Replace with your trigger element's selector // Wait for the calendar to load to avoid race conditions $I->waitForElementVisible('.datepicker-calendar-container', 10);
Step 2: Navigate to the Target Year
Most datepickers let you switch years via prev/next buttons. Loop until you reach your target year:
$targetYear = '2024'; $currentYear = $I->grabTextFrom('.datepicker-year-display'); // Replace with your year element selector while ($currentYear !== $targetYear) { // Click the "next year" button (use .datepicker-prev-year if going backward) $I->click('.datepicker-next-year'); $currentYear = $I->grabTextFrom('.datepicker-year-display'); }
Step 3: Select the Target Month
Depending on your datepicker, this could be a dropdown or clickable month labels:
// If using a dropdown selector $I->selectOption('.datepicker-month-select', 'June'); // Or use the month number, e.g., '6' // If using clickable month labels (adjust XPath to match your structure) $targetMonth = 'June'; $I->click("//div[contains(@class, 'datepicker-month') and normalize-space(text())='$targetMonth']");
Step 4: Click the Target Day
Finally, locate and click the specific day:
$targetDay = '15'; // Ensure the day isn't disabled before clicking $I->seeElementNotDisabled("//td[contains(@class, 'datepicker-day') and text()='$targetDay']"); $I->click("//td[contains(@class, 'datepicker-day') and text()='$targetDay']");
Key Notes for Success
- Use the right selectors: Inspect your datepicker with browser dev tools (F12) to get accurate CSS/XPath selectors—every datepicker (Bootstrap, jQuery UI, custom) has unique class names.
- Add waits: Always use
waitForElementVisible()orwaitForElementClickable()to avoid Selenium trying to interact with elements that haven’t loaded yet. - Handle edge cases: If your target date is in a different month/year, add a max iteration limit to your year loop to prevent infinite runs.
内容的提问来源于stack exchange,提问作者Harsh Patel

