dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.52k stars 10.04k forks source link

Add support for other date/time fields #12376

Closed rynowak closed 3 years ago

rynowak commented 5 years ago

We have good support in the box for doing binding correctly to <input type="date" /> fields using @bind and <InputDate>. We haven't added support for the other HTML5 date/time quantities like month.

Right now users can work around this by manually specifying the format:

<input type="datetimelocal" @bind="someDateTimeOffset" @bind:format="yyyy-MM-ddThh:mm" />

What's missing for us to have good in the box support would be to:


We're not doing this right now because we haven't gotten many requests for it, and users can easily work around the missing support by specifying the format. If we do add support it won't be a breaking change to anyone using the workaround because a user-specified format always wins over a framework-provided default.

EdCharbeneau commented 4 years ago

@pranavkm I wanted to clear up the specs before working on this item.

These functionalities are to be added to the InputDate component only, or is there another area of the codebase that will need support first? Is there any guidance on how the InputDate type property should be handled [string, enum]?

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/month Month will need to default to the first day of the month to properly map to a DateTime.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time Time will need to include a bogus date and map to DateTime or map to a TimeSpan.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/week Week does not represent a DateTime value, but a week number or possibly a TimeSpan.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local datetime: The type "datetime" is obsolete datetime-local: The type "datetime-local" might be hit/miss. See the note from Mozilla below:

Because of the limited browser support for datetime-local, and the variations in how the inputs work, it may currently still be best to use a framework or library to present these, or to use a custom input of your own. Another option is to use separate date and time inputs, each of which is more widely supported than datetime-local.

pranavkm commented 4 years ago

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/month Month will need to default to the first day of the month to properly map to a DateTime.

πŸ‘

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time Time will need to include a bogus date and map to DateTime or map to a TimeSpan.

We can use the current date as the date + time.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/week Week does not represent a DateTime value, but a week number or possibly a TimeSpan.

:+1:

EdCharbeneau commented 4 years ago

@pranavkm I added some functionality to the InputDate component for Month and Time scenarios in addition to Date.

You can control the type attribute via DateInputType enum which will display the corresponding UI and map the appropriate values to a DateTime.

Usage:

<EditForm Model="myform" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <label>Date Input</label>
    <InputDate @bind-Value="@myform.MyDate"></InputDateTime>
    <label>Month Input</label>
    <InputDate DateInputType="DateInputType.Month" @bind-Value="@myform.MyMonth"></InputDateTime>
    <label>Time Input</label>
    <InputDate DateInputType="DateInputType.Time" @bind-Value="@myform.MyTime"></InputDateTime>
    <button type="submit">Submit</button>
</EditForm>

Can you please review the component and see if the approach is valid? If we're on the right track I'll work on getting the proper tests going and submit a PR.

https://github.com/EdCharbeneau/aspnetcore/blob/feature-blazor-InputDate/src/Components/Web/src/Forms/InputDate.cs

Testing I was unable to get the Selenium tests to run. I'm working through some installation issues with JAVA.

pranavkm commented 4 years ago

Yup, this looks great.

I was unable to get the Selenium tests to run. I'm working through some installation issues with JAVA.

@captainsafia another data point in case you were collecting these.

captainsafia commented 4 years ago

@EdCharbeneau Can you share a stack trace of the error if there was any?

EdCharbeneau commented 4 years ago
  1. error I get from the CLI.
FAIL tests/DefaultReconnectionHandler.test.ts
    ΓùÅ Test suite failed to run

      TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
      src/Platform/Profiling.ts:127:44 - error TS2304: Cannot find name 'BINDING'.

      127     return typeof str === 'string' ? str : BINDING.conv_string(str);
                                                     ~~~~~~~
  1. I have a JAVA error when trying to run tests from Visual Studio. I'm re-intalling the JAVA SDK now to see if this fixes the problem.

Question: How do I run individual tests using ./build.cmd -test

captainsafia commented 4 years ago

For the first error, take a look at the fix introduced in https://github.com/dotnet/aspnetcore/pull/24026.

For running individual tests, you can try activating the preview version of dotnet using the activiation script (source activate.sh or . ./activate.ps1 depending on your environment). Then on the command line, you can cd into the test project and run dotnet test.

If you are using VS, you can use the test runner in VS to run individual test classes.

EdCharbeneau commented 4 years ago

Running from within VS I get:

53>C:\Users\edcha\source\aspnet\src\Shared\E2ETesting\E2ETesting.targets(43,5): error MSB3073: The command "java -version" exited with code 9009.
53>Done building project "Microsoft.AspNetCore.Components.E2ETests.csproj" -- FAILED.

Which points to this broken link:

    <!-- JAVA -->
    <!-- https://github.com/dotnet/aspnetcore-internal/issues/2555 -->
    <Message Importance="High" Text="Ensuring JAVA is available" />
    <Exec Command="java -version" />
    <Message Importance="High" Text="JAVA is available on the PATH" />

Update: I fixed the error by adding the JAVA path as follows. https://javatutorial.net/set-java-home-windows-10

EdCharbeneau commented 4 years ago

@captainsafia Selenium doesn't seem to work when running tests within VS. I haven't tried from the CLI.

  Source: AuthTest.cs line 71
   Duration: 4.4 sec

  Message: 
    OpenQA.Selenium.BrowserAssertFailedException : Xunit.Sdk.NotEmptyException: Assert.NotEmpty() Failure
       at Xunit.Assert.NotEmpty(IEnumerable collection) in C:\Dev\xunit\xunit\src\xunit.assert\Asserts\CollectionAsserts.cs:line 331
       at Microsoft.AspNetCore.E2ETesting.WaitAssert.<>c__DisplayClass15_0.<Exists>b__0() in C:\Users\edcha\source\aspnet\src\Shared\E2ETesting\WaitAssert.cs:line 67
       at Microsoft.AspNetCore.E2ETesting.WaitAssert.<>c__DisplayClass18_0`1.<WaitAssertCore>b__0(IWebDriver _) in C:\Users\edcha\source\aspnet\src\Shared\E2ETesting\WaitAssert.cs:line 98
    Screen shot captured at 'C:\Users\edcha\source\aspnet\src\Components\test\E2ETest\bin\screenshots\39bc71310d9748b08a77dfdfb580a793.png'
    Encountered browser errors
    [2020-07-21T17:49:38Z] [Severe] http://127.0.0.1:62922/subdir - Failed to load resource: the server responded with a status of 404 (Not Found)Page content:
    <head></head><body></body>

    ---- Assert.NotEmpty() Failure
  Stack Trace: 
    WaitAssert.WaitAssertCore[TResult](IWebDriver driver, Func`1 assertion, TimeSpan timeout) line 126
    WaitAssert.Exists(IWebDriver driver, By finder, TimeSpan timeout) line 64
    WaitAssert.Exists(IWebDriver driver, By finder) line 51
    BasicTestAppWebDriverExtensions.WaitUntilTestSelectorReady(IWebDriver browser) line 21
    BasicTestAppWebDriverExtensions.MountTestComponent[TComponent](IWebDriver browser) line 12
    AuthTest.MountAndNavigateToAuthTest(String authLinkText) line 232
    AuthTest.CascadingAuthenticationState_Authenticated() line 75
    ----- Inner Stack Trace -----
    <>c__DisplayClass15_0.<Exists>b__0() line 67
    <>c__DisplayClass18_0`1.<WaitAssertCore>b__0(IWebDriver _) line 98
captainsafia commented 4 years ago

@EdCharbeneau Do you see this test failure on all tests? Typically, this failure will occur due to loading delays in Selenium. In this case, whatever button or element we are looking for in the UI hasn't waited yet.

EdCharbeneau commented 4 years ago

I ran e2e tests again and here is the result. 257 errors

There are roughly two error types, the one I posted above and the following.

    OpenQA.Selenium.BrowserAssertFailedException : Xunit.Sdk.NotEmptyException: Assert.NotEmpty() Failure
       at Xunit.Assert.NotEmpty(IEnumerable collection) in C:\Dev\xunit\xunit\src\xunit.assert\Asserts\CollectionAsserts.cs:line 331
       at Microsoft.AspNetCore.E2ETesting.WaitAssert.<>c__DisplayClass15_0.<Exists>b__0() in C:\Users\edcha\source\aspnet\src\Shared\E2ETesting\WaitAssert.cs:line 67
       at Microsoft.AspNetCore.E2ETesting.WaitAssert.<>c__DisplayClass18_0`1.<WaitAssertCore>b__0(IWebDriver _) in C:\Users\edcha\source\aspnet\src\Shared\E2ETesting\WaitAssert.cs:line 98
    Screen shot captured at 'C:\Users\edcha\source\aspnet\src\Components\test\E2ETest\bin\screenshots\b4ff080bf0df42748349410ac1e324e7.png'
    Page content:
    <head>
        <meta charset="utf-8">
        <title>Basic test app</title>
        <base href="/subdir/">
        <link href="style.css" rel="stylesheet">

        <!-- Used by ExternalContentPackage -->
        <link href="_content/TestContentPackage/styles.css" rel="stylesheet">
    </head>

    <body>
        <root>Loading...</root>

        <!-- Explicit display:none required so StartupErrorNotificationTest can observe it change -->
        <div id="blazor-error-ui" style="display: none;">
            An unhandled error has occurred.
            <a href="" class="reload">Reload</a>
            <a class="dismiss" style="cursor: pointer;">πŸ—™</a>
        </div>

        <!-- Used for specific test cases -->
        <script src="js/jsinteroptests.js"></script>
        <script src="js/webComponentPerformingJsInterop.js"></script>

        <script>
            // Used by ElementRefComponent
            function setElementValue(element, newValue) {
                element.value = newValue;
                return element.value;
            }

            function navigationManagerNavigate() {
                Blazor.navigateTo('/subdir/some-path');
            }

            function getCurrentUrl() {
                return location.href;
            }
        </script>
        <script src="_framework/blazor.webassembly.js"></script>

        <!-- Used by ExternalContentPackage -->
        <script src="_content/TestContentPackage/prompt.js"></script>

    </body>

    ---- Assert.NotEmpty() Failure

Using > ./startvs.cmd

e2e

captainsafia commented 4 years ago

@EdCharbeneau Yeah, I think Selenium might be a little (OK, very) flaky on your machine. As you can see from the error, the web app is still on the Loading... screen when the failure occurs. This indicates that it's probably related to a timeout when searching for the element.

Typically, in these scenarios, I'll ensure that the E2E tests related to my code change are working (sometimes by spot validating a few) and then push to a PR and see what results I get in the CI from this.

MackinnonBuck commented 3 years ago

Done in #34594