-
Notifications
You must be signed in to change notification settings - Fork 4.6k
fix: Invalid Date Display in Table Widget's Date Column When Using Unix Timestamp (ms) #36455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
5ab2834
1a4ebe9
c97031f
6b6b7a8
94ef32d
da89194
2621b9a
877f4ce
68facfb
33da955
d6ec6ae
2ec53d1
4b5f373
aca19a8
36c32d6
d8701f2
17fa7e9
2abc737
17e8f41
dfe7b65
b13f966
6a3cae7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| import { | ||
| agHelper, | ||
| entityExplorer, | ||
| propPane, | ||
| table, | ||
| } from "../../../../../support/Objects/ObjectsCore"; | ||
|
|
||
| import EditorNavigation, { | ||
| EntityType, | ||
| } from "../../../../../support/Pages/EditorNavigation"; | ||
| import { tableV2DateTestData } from "./fixtures"; | ||
| import { getFormattedTomorrowDates } from "./helpers"; | ||
|
|
||
| describe( | ||
| "Table widget date column type validation", | ||
| { tags: ["@tag.Widget", "@tag.Table"] }, | ||
| () => { | ||
| before(() => { | ||
| entityExplorer.DragNDropWidget("tablewidgetv2", 350, 500); | ||
| EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); | ||
| propPane.ToggleJSMode("Table data", true); | ||
| propPane.UpdatePropertyFieldValue("Table data", tableV2DateTestData); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| propPane.NavigateBackToPropertyPane(false); | ||
| }); | ||
|
|
||
| const setEditableDateFormats = (format: string) => { | ||
| // Update date format property | ||
| propPane.ToggleJSMode("Date format", true); | ||
| propPane.UpdatePropertyFieldValue("Date format", format); | ||
|
|
||
| // Update display format property | ||
| propPane.ToggleJSMode("Display format", true); | ||
| propPane.UpdatePropertyFieldValue("Display format", "YYYY-MM-DD"); | ||
|
|
||
| // Toggle editable | ||
| propPane.TogglePropertyState("Editable", "On"); | ||
| }; | ||
|
|
||
| const clickAndValidateDateCell = (row: number, column: number) => { | ||
| // Click unix cell edit | ||
| table.ClickOnEditIcon(row, column); | ||
|
|
||
| // Click on specific date within | ||
| agHelper.GetNClick( | ||
| `${table._dateInputPopover} [aria-label='${getFormattedTomorrowDates().verboseFormat}']`, | ||
| ); | ||
|
Comment on lines
+47
to
+49
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use locator variables and data- attributes for selectors instead of plain strings* In the following selector: `${table._dateInputPopover} [aria-label='${getFormattedTomorrowDates().verboseFormat}']`You're using a plain string with an attribute selector. To enhance the robustness and maintainability of your tests, please use locator variables and |
||
|
|
||
| // Check that date is set in column | ||
| table | ||
| .ReadTableRowColumnData(row, column, "v2") | ||
| .then((val) => | ||
| expect(val).to.equal(getFormattedTomorrowDates().isoFormat), | ||
| ); | ||
| }; | ||
|
|
||
| it("1. should allow inline editing of Unix Timestamp in seconds (unix/s)", () => { | ||
| table.ChangeColumnType("unix/s", "Date"); | ||
| setEditableDateFormats("Epoch"); | ||
| clickAndValidateDateCell(0, 0); | ||
| }); | ||
|
|
||
| it("2. should allow inline editing of Unix Timestamp in milliseconds (unix/ms)", () => { | ||
| table.ChangeColumnType("unix/ms", "Date"); | ||
| setEditableDateFormats("Milliseconds"); | ||
| clickAndValidateDateCell(0, 1); | ||
| }); | ||
|
|
||
| it("3. should allow inline editing of date in YYYY-MM-DD format", () => { | ||
| table.ChangeColumnType("yyyy-mm-dd", "Date"); | ||
| setEditableDateFormats("YYYY-MM-DD"); | ||
| clickAndValidateDateCell(0, 2); | ||
| }); | ||
|
|
||
| it("4. should allow inline editing of date in YYYY-MM-DD HH:mm format", () => { | ||
| table.ChangeColumnType("yyyy-mm-dd hh:mm", "Date"); | ||
| setEditableDateFormats("YYYY-MM-DD HH:mm"); | ||
| clickAndValidateDateCell(0, 3); | ||
| }); | ||
|
|
||
| it("5. should allow inline editing of date in ISO 8601 format (YYYY-MM-DDTHH:mm:ss)", () => { | ||
| table.ChangeColumnType("yyyy-mm-ddTHH:mm:ss", "Date"); | ||
| setEditableDateFormats("YYYY-MM-DDTHH:mm:ss"); | ||
| clickAndValidateDateCell(0, 4); | ||
| }); | ||
|
|
||
| it("6. should allow inline editing of date in YYYY-MM-DD HH:mm:ss format", () => { | ||
| table.ChangeColumnType("yyyy-mm-dd hh:mm:ss", "Date"); | ||
| setEditableDateFormats("YYYY-MM-DD HH:mm:ss"); | ||
| clickAndValidateDateCell(0, 5); | ||
| }); | ||
|
|
||
| it("7. should allow inline editing of date in 'do MMM yyyy' format", () => { | ||
| table.ChangeColumnType("do MMM yyyy", "Date"); | ||
| setEditableDateFormats("Do MMM YYYY"); | ||
| clickAndValidateDateCell(0, 6); | ||
| }); | ||
|
|
||
| it("8. should allow inline editing of date in DD/MM/YYYY format", () => { | ||
| table.ChangeColumnType("dd/mm/yyyy", "Date"); | ||
| setEditableDateFormats("DD/MM/YYYY"); | ||
| clickAndValidateDateCell(0, 7); | ||
| }); | ||
|
|
||
| it("9. should allow inline editing of date in DD/MM/YYYY HH:mm format", () => { | ||
| table.ChangeColumnType("dd/mm/yyyy hh:mm", "Date"); | ||
| setEditableDateFormats("DD/MM/YYYY HH:mm"); | ||
| clickAndValidateDateCell(0, 8); | ||
| }); | ||
|
|
||
| it("10. should allow inline editing of date in LLL (Month Day, Year Time) format", () => { | ||
| table.ChangeColumnType("lll", "Date"); | ||
| setEditableDateFormats("LLL"); | ||
| clickAndValidateDateCell(0, 9); | ||
| }); | ||
|
|
||
| it("11. should allow inline editing of date in LL (Month Day, Year) format", () => { | ||
| table.ChangeColumnType("ll", "Date"); | ||
| setEditableDateFormats("LL"); | ||
| clickAndValidateDateCell(0, 10); | ||
| }); | ||
|
|
||
| it("12. should allow inline editing of date in 'D MMMM, YYYY' format", () => { | ||
| table.ChangeColumnType("d mmmm, yyyy", "Date"); | ||
| setEditableDateFormats("D MMMM, YYYY"); | ||
| clickAndValidateDateCell(0, 11); | ||
| }); | ||
|
|
||
| it("13. should allow inline editing of date in 'h:mm A D MMMM, YYYY' format", () => { | ||
| table.ChangeColumnType("h:mm A d mmmm, yyyy", "Date"); | ||
| setEditableDateFormats("h:mm A D MMMM, YYYY"); | ||
| clickAndValidateDateCell(0, 12); | ||
| }); | ||
|
|
||
| it("14. should allow inline editing of date in MM-DD-YYYY format", () => { | ||
| table.ChangeColumnType("mm-dd-yyyy", "Date"); | ||
| setEditableDateFormats("MM-DD-YYYY"); | ||
| clickAndValidateDateCell(0, 13); | ||
| }); | ||
|
|
||
| it("15. should allow inline editing of date in DD-MM-YYYY format", () => { | ||
| table.ChangeColumnType("dd-mm-yyyy", "Date"); | ||
| setEditableDateFormats("DD-MM-YYYY"); | ||
| clickAndValidateDateCell(0, 14); | ||
| }); | ||
|
|
||
| it("16. should allow inline editing of date in MM/DD/YYYY format", () => { | ||
| table.ChangeColumnType("mm/dd/yyyy", "Date"); | ||
| setEditableDateFormats("MM/DD/YYYY"); | ||
| clickAndValidateDateCell(0, 15); | ||
| }); | ||
|
|
||
| it("17. should allow inline editing of date in DD/MM/YY format", () => { | ||
| table.ChangeColumnType("dd/mm/yy", "Date"); | ||
| setEditableDateFormats("DD/MM/YY"); | ||
| clickAndValidateDateCell(0, 16); | ||
| }); | ||
|
|
||
| it("18. should allow inline editing of date in MM/DD/YY format", () => { | ||
| table.ChangeColumnType("mm/dd/yy", "Date"); | ||
| setEditableDateFormats("MM/DD/YY"); | ||
| clickAndValidateDateCell(0, 17); | ||
| }); | ||
| }, | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| export const tableV2DateTestData = ` | ||
|
sagar-qa007 marked this conversation as resolved.
Outdated
|
||
| {{ | ||
| [ | ||
| { | ||
| "unix/s": 1727212200, | ||
| "unix/ms": 1727212200000, | ||
| "yyyy-mm-dd": "2024-09-25", | ||
| "yyyy-mm-dd hh:mm": "2024-09-25 14:30", | ||
| iso8601: "2024-09-25T14:30:00.000Z", | ||
| "yyyy-mm-ddTHH:mm:ss": "2024-09-25T14:30:00", | ||
| "yyyy-mm-dd hh:mm:ss": "2024-09-25 02:30:00", | ||
| "do MMM yyyy": "25th Sep 2024", | ||
| "dd/mm/yyyy": "25/09/2024", | ||
| "dd/mm/yyyy hh:mm": "25/09/2024 14:30", | ||
| lll: "September 25, 2024 2:30 PM", | ||
| ll: "September 25, 2024", | ||
| "d mmmm, yyyy": "25 September, 2024", | ||
| "h:mm A d mmmm, yyyy": "2:30 PM 25 September, 2024", | ||
| "mm-dd-yyyy": "09-25-2024", | ||
| "dd-mm-yyyy": "25-09-2024", | ||
| "mm/dd/yyyy": "09/25/2024", | ||
| "dd/mm/yy": "25/09/24", | ||
| "mm/dd/yy": "09/25/24", | ||
| }, | ||
| { | ||
| "unix/s": 1695676200, | ||
| "unix/ms": 1695676200000, | ||
| "yyyy-mm-dd": "2023-09-25", | ||
| "yyyy-mm-dd hh:mm": "2023-09-25 10:15", | ||
| iso8601: "2023-09-25T10:15:00.000Z", | ||
| "yyyy-mm-ddTHH:mm:ss": "2023-09-25T10:15:00", | ||
| "yyyy-mm-dd hh:mm:ss": "2023-09-25 10:15:00", | ||
| "do MMM yyyy": "25th Sep 2023", | ||
| "dd/mm/yyyy": "25/09/2023", | ||
| "dd/mm/yyyy hh:mm": "25/09/2023 10:15", | ||
| lll: "September 25, 2023 10:15 AM", | ||
| ll: "September 25, 2023", | ||
| "d mmmm, yyyy": "25 September, 2023", | ||
| "h:mm A d mmmm, yyyy": "10:15 AM 25 September, 2023", | ||
| "mm-dd-yyyy": "09-25-2023", | ||
| "dd-mm-yyyy": "25-09-2023", | ||
| "mm/dd/yyyy": "09/25/2023", | ||
| "dd/mm/yy": "25/09/23", | ||
| "mm/dd/yy": "09/25/23", | ||
| }, | ||
| { | ||
| "unix/s": 1664140200, | ||
| "unix/ms": 1664140200000, | ||
| "yyyy-mm-dd": "2022-09-25", | ||
| "yyyy-mm-dd hh:mm": "2022-09-25 08:45", | ||
| iso8601: "2022-09-25T08:45:00.000Z", | ||
| "yyyy-mm-ddTHH:mm:ss": "2022-09-25T08:45:00", | ||
| "yyyy-mm-dd hh:mm:ss": "2022-09-25 08:45:00", | ||
| "do MMM yyyy": "25th Sep 2022", | ||
| "dd/mm/yyyy": "25/09/2022", | ||
| "dd/mm/yyyy hh:mm": "25/09/2022 08:45", | ||
| lll: "September 25, 2022 8:45 AM", | ||
| ll: "September 25, 2022", | ||
| "d mmmm, yyyy": "25 September, 2022", | ||
| "h:mm A d mmmm, yyyy": "8:45 AM 25 September, 2022", | ||
| "mm-dd-yyyy": "09-25-2022", | ||
| "dd-mm-yyyy": "25-09-2022", | ||
| "mm/dd/yyyy": "09/25/2022", | ||
| "dd/mm/yy": "25/09/22", | ||
| "mm/dd/yy": "09/25/22", | ||
| }, | ||
| ] | ||
| }} | ||
| `; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Let's expand our test data horizons, shall we? While our current set of dates is a good start, we can make it even better! Here are some suggestions to challenge our table component further:
By expanding our test data, we'll ensure our table component can handle any date thrown at it, just like how you handle any question in class! |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| /** | ||
|
sagar-qa007 marked this conversation as resolved.
Outdated
|
||
| * Helper function to get formatted date strings for tomorrow's date. | ||
| * | ||
| * @returns {Object} An object containing: | ||
| * - verbose format (e.g., "Sat Sep 21 2024") | ||
| * - ISO date format (e.g., "2024-09-21") | ||
| */ | ||
| export function getFormattedTomorrowDates() { | ||
| // Create a new Date object for today | ||
| const tomorrow = new Date(); | ||
|
|
||
| // Set the date to tomorrow by adding 1 to today's date | ||
| tomorrow.setDate(tomorrow.getDate() + 1); | ||
|
|
||
| // Format tomorrow's date in verbose form (e.g., "Sat Sep 21 2024") | ||
| const verboseFormat = tomorrow | ||
| .toLocaleDateString("en-US", { | ||
| weekday: "short", | ||
| year: "numeric", | ||
| month: "short", | ||
| day: "2-digit", | ||
| }) | ||
| .replace(/,/g, ""); // Remove commas from the formatted string | ||
|
|
||
| // Format tomorrow's date in ISO form (e.g., "2024-09-21") | ||
| const isoFormat = tomorrow.toISOString().split("T")[0]; // Extract the date part only | ||
|
|
||
| // Return both formatted date strings as an object | ||
| return { | ||
| verboseFormat, | ||
| isoFormat, | ||
| }; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using 'after' and 'afterEach' in test cases
I notice that you've included an
afterEachhook in your test suite. To ensure each test remains independent and to avoid unintended side effects, it's best practice to avoid usingafterandafterEachin test cases. Consider integrating any necessary cleanup directly within your tests or restructuring your code to eliminate the need for these global hooks.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jacquesikot can you please check why we need afterEach here? It is violating best practices and we need to avoid it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.