Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanTsukanov committed Sep 4, 2024
2 parents 089a49f + 88d0e1f commit 92e1061
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 19 deletions.
29 changes: 16 additions & 13 deletions packages/survey-core/src/mask/mask_datetime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ export class InputMaskDateTime extends InputMaskPattern {
private getMaskedStrFromISO(str: string): string {
let date = new Date(str);
this.initInputDateTimeData();
if (!this.hasTimePart) {
date = new Date(str + "T00:00:00");
}
if(!this.hasDatePart) {
date = new Date(this.defaultDate + str);
}
Expand All @@ -214,35 +217,35 @@ export class InputMaskDateTime extends InputMaskPattern {
switch(lexem.type) {
case "hour": {
if (!this.is12Hours) {
inputData.value = date.getUTCHours().toString();
inputData.value = date.getHours().toString();
} else {
inputData.value = ((date.getUTCHours() - 1) % this.twelve + 1).toString();
inputData.value = ((date.getHours() - 1) % this.twelve + 1).toString();
}
break;
}
case "minute": {
inputData.value = date.getUTCMinutes().toString();
inputData.value = date.getMinutes().toString();
break;
}
case "second": {
inputData.value = date.getUTCSeconds().toString();
inputData.value = date.getSeconds().toString();
break;
}
case "timeMarker": {
const marker = (date.getUTCHours() >= this.twelve) ? "pm" : "am";
const marker = (date.getHours() >= this.twelve) ? "pm" : "am";
inputData.value = lexem.upperCase ? marker.toUpperCase() : marker;
break;
}
case "day": {
inputData.value = date.getUTCDate().toString();
inputData.value = date.getDate().toString();
break;
}
case "month": {
inputData.value = (date.getUTCMonth() + 1).toString();
inputData.value = (date.getMonth() + 1).toString();
break;
}
case "year": {
let year = date.getUTCFullYear();
let year = date.getFullYear();
if(lexem.count == 2) year = year % 100;
inputData.value = year.toString();
break;
Expand Down Expand Up @@ -314,7 +317,7 @@ export class InputMaskDateTime extends InputMaskPattern {
private createIDateTimeCompositionWithDefaults(dateTime: IDateTimeComposition, isUpperLimit: boolean): IDateTimeComposition {
const min = dateTime.min;
const max = dateTime.max;
const year = dateTime.year !== undefined ? dateTime.year : getDefaultYearForValidation(min.getUTCFullYear(), max.getUTCFullYear());
const year = dateTime.year !== undefined ? dateTime.year : getDefaultYearForValidation(min.getFullYear(), max.getFullYear());
const month = dateTime.month !== undefined ? dateTime.month : (isUpperLimit && this.hasDatePart ? 12 : 1);
const day = dateTime.day !== undefined ? dateTime.day : (isUpperLimit && this.hasDatePart ? this.getMaxDateForMonth(year, month) : 1);
const hour = dateTime.hour !== undefined ? dateTime.hour : (isUpperLimit ? 23 : 0);
Expand All @@ -332,7 +335,7 @@ export class InputMaskDateTime extends InputMaskPattern {
private isDateValid(dateTime: IDateTimeComposition): boolean {
const min = dateTime.min;
const max = dateTime.max;
const year = dateTime.year !== undefined ? dateTime.year : getDefaultYearForValidation(min.getUTCFullYear(), max.getUTCFullYear());
const year = dateTime.year !== undefined ? dateTime.year : getDefaultYearForValidation(min.getFullYear(), max.getFullYear());
const month = dateTime.month !== undefined ? dateTime.month : 1;
const day = dateTime.day !== undefined ? dateTime.day : 1;
const monthIndex = month - 1;
Expand All @@ -341,9 +344,9 @@ export class InputMaskDateTime extends InputMaskPattern {
const dateH = new Date(this.getISO_8601Format(this.createIDateTimeCompositionWithDefaults(dateTime, true)));

return !isNaN(date as any) &&
date.getUTCDate() === day &&
date.getUTCMonth() === monthIndex &&
date.getUTCFullYear() === year &&
date.getDate() === day &&
date.getMonth() === monthIndex &&
date.getFullYear() === year &&
dateH >= dateTime.min && date <= dateTime.max;
}

Expand Down
7 changes: 5 additions & 2 deletions packages/survey-core/src/question_text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,11 @@ export class QuestionTextModel extends QuestionTextBase {
}
if(this.inputType === "month") {
const d = new Date(newValue);
const m = d.getUTCMonth() + 1;
return d.getUTCFullYear() + "-" + (m < 10 ? "0" : "") + m;
const isUtc = d.toISOString().indexOf(newValue) == 0 && newValue.indexOf("T") == -1;
const month = isUtc ? d.getUTCMonth() : d.getMonth();
const year = isUtc ? d.getUTCFullYear() : d.getFullYear();
const m = month + 1;
return year + "-" + (m < 10 ? "0" : "") + m;
}
return newValue;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/survey-core/tests/mask/mask_datetime_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ QUnit.test("get getMaskedValue value from ISO m/d/yy", function (assert) {
const maskInstance = new InputMaskDateTime();
maskInstance.pattern = "m/d/yy";
assert.equal(maskInstance.getMaskedValue("2024-12-05"), "12/5/24");
assert.equal(maskInstance.getMaskedValue("988-01-05"), "1/5/88");
assert.equal(maskInstance.getMaskedValue("1988-01-05"), "1/5/88");
assert.equal(maskInstance.getMaskedValue("2024-13-05"), "m/d/yy");
});

Expand Down
12 changes: 12 additions & 0 deletions testCafe/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,3 +542,15 @@ export function filterIsInViewport(node) {
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
export async function setTimeZoneUnsafe(t, timezone) {
//Please note that the workaround uses internal API, which can be changed in the future, so you should use it carefully.
//https://stackoverflow.com/questions/75837713/timezone-tests-in-testcafe
const browserConnection = t["testRun"].browserConnection;
const providerPlugin = browserConnection.provider.plugin;
const browserClient = providerPlugin._getBrowserProtocolClient(providerPlugin.openedBrowsers[browserConnection.id]);
const cdpClient = await browserClient.getActiveClient();
await cdpClient.Emulation.setTimezoneOverride({ timezoneId: timezone });
}
export function getTimeZone() {
return ClientFunction(() => Intl.DateTimeFormat().resolvedOptions().timeZone)();
}
44 changes: 42 additions & 2 deletions testCafe/questions/input_mask.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Selector, fixture, test, ClientFunction } from "testcafe";
import { frameworks, url, initSurvey, getSurveyResult } from "../helper";
import { frameworks, url, initSurvey, getSurveyResult, setTimeZoneUnsafe, getTimeZone } from "../helper";
const title = "Input mask";

frameworks.forEach((framework) => {
Expand Down Expand Up @@ -104,4 +104,44 @@ frameworks.forEach((framework) => {
.pressKey("tab")
.expect(Selector("input").value).eql(emptyValue);
});
});

test("Test mask in western timezone", async (t) => {
const oldTimeZone = await getTimeZone();
await setTimeZoneUnsafe(t, "America/Los_Angeles");
await initSurvey(framework, {
focusFirstQuestionAutomatic: true,
questions: [
{
name: "name",
type: "text",
maskType: "datetime",
maskSettings: {
pattern: "HH:MM"
}
}, {
"type": "text",
"name": "yearInput",
"title": "Year Input (Input Mask)",
"maskType": "datetime",
"maskSettings": {
"pattern": "yyyy"
},
"placeholder": "YYYY"
}]
});

await t
.expect(getTimeZone()).eql("America/Los_Angeles")
.pressKey("1 2 3 4 tab 2 0 2 2 tab")
.expect(Selector("input").nth(0).value).eql("12:34")
.expect(Selector("input").nth(1).value).eql("2022")
.click("input[value=Complete]");

const surveyResult = await getSurveyResult();
await t.expect(surveyResult).eql({
name: "12:34",
yearInput: "2022"
});
await setTimeZoneUnsafe(t, oldTimeZone);
});
});
28 changes: 27 additions & 1 deletion testCafe/questions/text.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { frameworks, url, initSurvey, getSurveyResult, getQuestionValue, getQuestionJson } from "../helper";
import { frameworks, url, initSurvey, getSurveyResult, getQuestionValue, getQuestionJson, getTimeZone, setTimeZoneUnsafe } from "../helper";
import { Selector, fixture, test, ClientFunction } from "testcafe";
// eslint-disable-next-line no-undef
const assert = require("assert");
Expand Down Expand Up @@ -243,4 +243,30 @@ frameworks.forEach((framework) => {
name: " ",
});
});
test("Test input type (month) in western timezone", async (t) => {
const oldTimeZone = await getTimeZone();
await setTimeZoneUnsafe(t, "America/Los_Angeles");
await initSurvey(framework, {
focusFirstQuestionAutomatic: true,
questions: [
{
"type": "text",
"name": "monthInput",
"title": "Month Input",
"inputType": "month"
}]
});

await t
.expect(getTimeZone()).eql("America/Los_Angeles")
.pressKey("M tab 2 0 2 4 tab")
.expect(Selector("input").nth(0).value).eql("2024-03")
.click("input[value=Complete]");

const surveyResult = await getSurveyResult();
await t.expect(surveyResult).eql({
monthInput: "2024-03"
});
await setTimeZoneUnsafe(t, oldTimeZone);
});
});

0 comments on commit 92e1061

Please sign in to comment.