aspnetcore/src/Components/test/E2ETest/Tests/GlobalizationTest.cs

222 lines
12 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Globalization;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
using Microsoft.AspNetCore.E2ETesting;
using OpenQA.Selenium;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.AspNetCore.Components.E2ETests.Tests
{
public abstract class GlobalizationTest<TServerFixture> : ServerTestBase<TServerFixture>
where TServerFixture : ServerFixture
{
public GlobalizationTest(BrowserFixture browserFixture, TServerFixture serverFixture, ITestOutputHelper output)
: base(browserFixture, serverFixture, output)
{
}
protected abstract void SetCulture(string culture);
/// <summary>
/// Blazor Server and these tests will use the application's UtcOffset when calculating DateTimeOffset when
/// an offset is not explicitly specified. Blazor WASM always calculates DateTimeOffsets as Utc.
/// We'll use <see cref="UtcOffset"/> to express this difference in calculating expected values in these tests.
/// </summary>
protected abstract TimeSpan UtcOffset { get; }
[Theory]
[InlineData("en-US")]
[InlineData("fr-FR")]
public void CanSetCultureAndParseCultueSensitiveNumbersAndDates(string culture)
{
var cultureInfo = CultureInfo.GetCultureInfo(culture);
SetCulture(culture);
// int
var input = Browser.FindElement(By.Id("input_type_text_int"));
var display = Browser.FindElement(By.Id("input_type_text_int_value"));
Browser.Equal(42.ToString(cultureInfo), () => display.Text);
input.Clear();
input.SendKeys(9000.ToString("0,000", cultureInfo));
input.SendKeys("\t");
Browser.Equal(9000.ToString(cultureInfo), () => display.Text);
// decimal
input = Browser.FindElement(By.Id("input_type_text_decimal"));
display = Browser.FindElement(By.Id("input_type_text_decimal_value"));
Browser.Equal(4.2m.ToString(cultureInfo), () => display.Text);
input.Clear();
input.SendKeys(9000.42m.ToString("0,000.00", cultureInfo));
input.SendKeys("\t");
Browser.Equal(9000.42m.ToString(cultureInfo), () => display.Text);
// datetime
input = Browser.FindElement(By.Id("input_type_text_datetime"));
display = Browser.FindElement(By.Id("input_type_text_datetime_value"));
Browser.Equal(new DateTime(1985, 3, 4).ToString(cultureInfo), () => display.Text);
input.ReplaceText(new DateTime(2000, 1, 2).ToString(cultureInfo));
input.SendKeys("\t");
Browser.Equal(new DateTime(2000, 1, 2).ToString(cultureInfo), () => display.Text);
// datetimeoffset
input = Browser.FindElement(By.Id("input_type_text_datetimeoffset"));
display = Browser.FindElement(By.Id("input_type_text_datetimeoffset_value"));
Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4), UtcOffset).ToString(cultureInfo), () => display.Text);
input.ReplaceText(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString(cultureInfo));
input.SendKeys("\t");
Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString(cultureInfo), () => display.Text);
}
// The logic is different for verifying culture-invariant fields. The problem is that the logic for what
// kinds of text a field accepts is determined by the browser and language - it's not general. So while
// type="number" and type="date" produce fixed-format and culture-invariant input/output via the "value"
// attribute - the actual input processing is harder to nail down. In practice this is only a problem
// with dates.
//
// For this reason we avoid sending keys directly to the field, and let two-way binding do its thing instead.
//
// A brief summary:
// 1. Input a value (invariant culture if using number field, or current culture to extra input if using date field)
// 2. trigger onchange
// 3. Verify "value" field (current culture)
// 4. Verify the input field's value attribute (invariant culture)
//
// We need to do step 4 to make sure that the value we're entering can "stick" in the form field.
// We can't use ".Text" because DOM reasons :(
[Theory]
[InlineData("en-US")]
[InlineData("fr-FR")]
public void CanSetCultureAndParseCultureInvariantNumbersAndDatesWithInputFields(string culture)
{
var cultureInfo = CultureInfo.GetCultureInfo(culture);
SetCulture(culture);
// int
var input = Browser.FindElement(By.Id("input_type_number_int"));
var display = Browser.FindElement(By.Id("input_type_number_int_value"));
Browser.Equal(42.ToString(cultureInfo), () => display.Text);
Browser.Equal(42.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
input.Clear();
input.SendKeys(9000.ToString(CultureInfo.InvariantCulture));
input.SendKeys("\t");
Browser.Equal(9000.ToString(cultureInfo), () => display.Text);
Browser.Equal(9000.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
// decimal
input = Browser.FindElement(By.Id("input_type_number_decimal"));
display = Browser.FindElement(By.Id("input_type_number_decimal_value"));
Browser.Equal(4.2m.ToString(cultureInfo), () => display.Text);
Browser.Equal(4.2m.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
input.Clear();
input.SendKeys(9000.42m.ToString(CultureInfo.InvariantCulture));
input.SendKeys("\t");
Browser.Equal(9000.42m.ToString(cultureInfo), () => display.Text);
Browser.Equal(9000.42m.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
// datetime
input = Browser.FindElement(By.Id("input_type_date_datetime"));
display = Browser.FindElement(By.Id("input_type_date_datetime_value"));
var extraInput = Browser.FindElement(By.Id("input_type_date_datetime_extrainput"));
Browser.Equal(new DateTime(1985, 3, 4).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTime(1985, 3, 4).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
extraInput.ReplaceText(new DateTime(2000, 1, 2).ToString(cultureInfo));
extraInput.SendKeys("\t");
Browser.Equal(new DateTime(2000, 1, 2).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTime(2000, 1, 2).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
// datetimeoffset
input = Browser.FindElement(By.Id("input_type_date_datetimeoffset"));
display = Browser.FindElement(By.Id("input_type_date_datetimeoffset_value"));
extraInput = Browser.FindElement(By.Id("input_type_date_datetimeoffset_extrainput"));
Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4), UtcOffset).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4), UtcOffset).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
extraInput.ReplaceText(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString(cultureInfo));
extraInput.SendKeys("\t");
Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
}
[Theory]
[InlineData("en-US")]
[InlineData("fr-FR")]
public void CanSetCultureAndParseCultureInvariantNumbersAndDatesWithFormComponents(string culture)
{
var cultureInfo = CultureInfo.GetCultureInfo(culture);
SetCulture(culture);
// int
var input = Browser.FindElement(By.Id("inputnumber_int"));
var display = Browser.FindElement(By.Id("inputnumber_int_value"));
Browser.Equal(42.ToString(cultureInfo), () => display.Text);
Browser.Equal(42.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
input.Clear();
input.SendKeys(9000.ToString(CultureInfo.InvariantCulture));
input.SendKeys("\t");
Browser.Equal(9000.ToString(cultureInfo), () => display.Text);
Browser.Equal(9000.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
// long
input = Browser.FindElement(By.Id("inputnumber_long"));
display = Browser.FindElement(By.Id("inputnumber_long_value"));
Browser.Equal(4200.ToString(cultureInfo), () => display.Text);
Browser.Equal(4200.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
input.Clear();
input.SendKeys(90000000000.ToString(CultureInfo.InvariantCulture));
input.SendKeys("\t");
Browser.Equal(90000000000.ToString(cultureInfo), () => display.Text);
Browser.Equal(90000000000.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
// decimal
input = Browser.FindElement(By.Id("inputnumber_decimal"));
display = Browser.FindElement(By.Id("inputnumber_decimal_value"));
Browser.Equal(4.2m.ToString(cultureInfo), () => display.Text);
Browser.Equal(4.2m.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
input.Clear();
input.SendKeys(9000.42m.ToString(CultureInfo.InvariantCulture));
input.SendKeys("\t");
Browser.Equal(9000.42m.ToString(cultureInfo), () => display.Text);
Browser.Equal(9000.42m.ToString(CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
// datetime
input = Browser.FindElement(By.Id("inputdate_datetime"));
display = Browser.FindElement(By.Id("inputdate_datetime_value"));
var extraInput = Browser.FindElement(By.Id("inputdate_datetime_extrainput"));
Browser.Equal(new DateTime(1985, 3, 4).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTime(1985, 3, 4).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
extraInput.ReplaceText(new DateTime(2000, 1, 2).ToString(cultureInfo));
extraInput.SendKeys("\t");
Browser.Equal(new DateTime(2000, 1, 2).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTime(2000, 1, 2).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
// datetimeoffset
input = Browser.FindElement(By.Id("inputdate_datetimeoffset"));
display = Browser.FindElement(By.Id("inputdate_datetimeoffset_value"));
extraInput = Browser.FindElement(By.Id("inputdate_datetimeoffset_extrainput"));
Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4), UtcOffset).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTimeOffset(new DateTime(1985, 3, 4), UtcOffset).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
extraInput.ReplaceText(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString(cultureInfo));
extraInput.SendKeys("\t");
Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString(cultureInfo), () => display.Text);
Browser.Equal(new DateTimeOffset(new DateTime(2000, 1, 2), UtcOffset).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), () => input.GetAttribute("value"));
}
}
}