jeudi 29 août 2019

TempData Empty on Redirect During SpecFlow Tests Only

I'm testing a .Net Core 2.2 web app using SpecFlow, Selenium, and ChromeDriver and am befuddled by something I've encountered.

I'm using TempData to pass data for an alert message between a page that posts data and a page that displays data. When deployed to IIS locally for debugging, etc, I see the TempData until it is consumed and displayed on a page as formatted message. However, I have a step in a SpecFlow scenario that fails when the alert isn't displayed because the TempData is empty. The SpecFlow scenario follows the same steps that are taken during manual testing.

I am testing a .Net Core 2.2 web project from a referenced XUnit/Specflow test project. The following relevant dependencies are used:

  • Microsoft.NetCore.App v2.2.0
  • SpecFlow v3.0.225
  • SpecFlow.xUnit v3.0.225
  • Selenium.WebDriver v3.141.0
  • Selenium.WebDriver.ChromeDriver v76.0.3809.12600

I have confirmed that TempData is populated as expected with the message data when debugging the application locally. Debugging the test shows that TempData is populated upon successful posting of form data but is empty when the resulting OnGet is processed during the redirect.

Here is the post handler for adding an account:

public async Task<IActionResult> OnPostAsync()
{
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Account.UserName, Email = Account.EmailAddress };
        var result = await _userManager.CreateAsync(user);

        if (result.Succeeded)
        {

            Dictionary<string, string> SuccessAlert = new Dictionary<string, string>()
            {
                { "Type", "success" },
                { "Title", "Account Added" },
                { "Text",  "Account for user " + Account.UserName + " was added successfully."}
            };

            TempData["Alert"] = SuccessAlert;

            _logger.LogInformation($"account added successfully. Alert title: {SuccessAlert["Title"]}");

            return RedirectToPage("/Accounts/Index", new
            {
                area = "Administration"
            });
        }

        foreach (var error in result.Errors)
        {
            ModelState.AddModelError("", error.Description);
        }

    }

    Dictionary<string, string> ErrorAlert = new Dictionary<string, string>()
            {
                { "Type", "error" },
                { "Title", "Uh-oh!" },
                { "Text",  "Account for user " + Account.UserName + " was not added. See errors below."}
            };

    TempData["Alert"] = ErrorAlert;

    return Page();
}

And the get handler for the /Accounts/Index page that the above redirects to upon successful completion (pretty basic):

public void OnGet()
{
    Accounts = _accountService.FindAll();
    _logger.LogInformation("AccountsIndexModel.OnGet");
    _logger.LogInformation($"Items in TempData: {TempData.Count}");
}

The following are snippets from log files corresponding to the logging in the code above.

Logs for manually adding an account:

2019-08-28 16:18:53.917 -04:00 First.Web.Areas.Administration.Accounts.AddAccountModel [Information] account added successfully. Alert title: Account Added
2019-08-28 16:19:08.587 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] AccountsIndexModel.OnGet
2019-08-28 16:19:08.588 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] Items in TempData: 1

And for the SpecFlow automated test:

2019-08-28 17:19:02.014 -04:00 First.Web.Areas.Administration.Accounts.AddAccountModel [Information] account added successfully. Alert title: Account Added
2019-08-28 17:19:02.105 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] AccountsIndexModel.OnGet
2019-08-28 17:19:02.105 -04:00 First.Web.Areas.Administration.Accounts.AccountsIndexModel [Information] Items in TempData: 0

Here's the SpecFlow scenario:

Scenario: Add new account succeeds
    Given I have access to the "Administration" module
    When I navigate to the "Add Account" page
        And I submit an account with values
            | accountname | emailaddress         |
            | mcullen     | mcullen@mnhockey.com |
    Then I should be on the "Accounts" page
        And I should see a success message with
            | title         | description      |
            | Account Added | Account for user |

And the step definition for the account submission step:

[When(@"I submit an account with values")]
public void WhenISubmitAnAccountWithValues(Table table)
{
    var accountName = "";
    var emailAddress = "";

    var row = table.Rows[0];

    row.TryGetValue("accountname", out accountName);
    row.TryGetValue("emailaddress", out emailAddress);

    _accountsAddPage.AccountNameField.SendKeys(accountName);
    _accountsAddPage.EmailAddressField.SendKeys(emailAddress);

    _accountsIndexPage = _accountsAddPage.Submit();

    _context.Set<string>("Accounts", "currentpage");
}

Aucun commentaire:

Enregistrer un commentaire