@@ -344,4 +344,146 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
344344await expect(page.locator('ion-datetime-button')).toContainText('Thu, November 02 01:22 AM');
345345});
346346});
347+348+test.describe(title('datetime-button: datetime constraints'), () => {
349+const fixedTime = new Date('2026-06-18T17:54:54.518Z');
350+351+const dateFormat = new Intl.DateTimeFormat('en-US', {
352+weekday: 'short',
353+month: 'long',
354+day: '2-digit',
355+});
356+const timeFormat = new Intl.DateTimeFormat('en-US', {
357+hour: '2-digit',
358+minute: '2-digit',
359+});
360+361+test.beforeEach(async ({ page }) => {
362+await page.clock.setFixedTime(fixedTime);
363+});
364+365+test('should default to exact current time with no constraints', async ({ page }, testInfo) => {
366+testInfo.annotations.push({
367+type: 'issue',
368+description: 'https://github.com/ionic-team/ionic-framework/issues/30183',
369+});
370+371+await page.setContent(
372+`
373+ <ion-datetime-button datetime="datetime"></ion-datetime-button>
374+ <ion-datetime id="datetime" presentation="date-time" locale="en-US"></ion-datetime>
375+ <script>
376+ const datetime = document.querySelector('ion-datetime');
377+ datetime.formatOptions = {
378+ date: {
379+ weekday: "short",
380+ month: "long",
381+ day: "2-digit"
382+ },
383+ time: {
384+ hour: "2-digit",
385+ minute: "2-digit"
386+ }
387+ }
388+ </script>
389+ `,
390+config
391+);
392+await page.locator('.datetime-ready').waitFor();
393+394+await expect(page.locator('#date-button')).toContainText(dateFormat.format(fixedTime));
395+await expect(page.locator('#time-button')).toContainText(timeFormat.format(fixedTime));
396+});
397+398+test('should obey minuteValues constraint', async ({ page }, testInfo) => {
399+testInfo.annotations.push({
400+type: 'issue',
401+description: 'https://github.com/ionic-team/ionic-framework/issues/30183',
402+});
403+404+await page.setContent(
405+`
406+ <ion-datetime-button datetime="datetime"></ion-datetime-button>
407+ <ion-datetime id="datetime" presentation="time" locale="en-US" minute-values="0"></ion-datetime>
408+ <script>
409+ const datetime = document.querySelector('ion-datetime');
410+ datetime.formatOptions = {
411+ time: {
412+ hour: "2-digit",
413+ minute: "2-digit"
414+ }
415+ }
416+ </script>
417+ `,
418+config
419+);
420+await page.locator('.datetime-ready').waitFor();
421+422+const expectedTime = new Date(fixedTime);
423+expectedTime.setMinutes(0);
424+425+await expect(page.locator('#time-button')).toContainText(timeFormat.format(expectedTime));
426+});
427+428+test('should obey hourValues constraint', async ({ page }, testInfo) => {
429+testInfo.annotations.push({
430+type: 'issue',
431+description: 'https://github.com/ionic-team/ionic-framework/issues/30183',
432+});
433+434+await page.setContent(
435+`
436+ <ion-datetime-button datetime="datetime"></ion-datetime-button>
437+ <ion-datetime id="datetime" presentation="time" locale="en-US" hour-values="0"></ion-datetime>
438+ <script>
439+ const datetime = document.querySelector('ion-datetime');
440+ datetime.formatOptions = {
441+ time: {
442+ hour: "2-digit",
443+ minute: "2-digit"
444+ }
445+ }
446+ </script>
447+ `,
448+config
449+);
450+await page.locator('.datetime-ready').waitFor();
451+452+const expectedTime = new Date(fixedTime);
453+expectedTime.setHours(0);
454+455+await expect(page.locator('#time-button')).toContainText(timeFormat.format(expectedTime));
456+});
457+458+test('should obey monthValues constraint', async ({ page }, testInfo) => {
459+testInfo.annotations.push({
460+type: 'issue',
461+description: 'https://github.com/ionic-team/ionic-framework/issues/30183',
462+});
463+464+await page.setContent(
465+`
466+ <ion-datetime-button datetime="datetime"></ion-datetime-button>
467+ <ion-datetime id="datetime" presentation="date" locale="en-US" month-values="1"></ion-datetime>
468+ <script>
469+ const datetime = document.querySelector('ion-datetime');
470+ datetime.formatOptions = {
471+ date: {
472+ weekday: "short",
473+ month: "long",
474+ day: "2-digit"
475+ }
476+ }
477+ </script>
478+ `,
479+config
480+);
481+await page.locator('.datetime-ready').waitFor();
482+483+const expectedTime = new Date(fixedTime);
484+expectedTime.setMonth(0);
485+486+await expect(page.locator('#date-button')).toContainText(dateFormat.format(expectedTime));
487+});
488+});
347489});