diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 275c0ef..6a09776 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -214,13 +214,6 @@ jobs: cat src/BankMore.Web/blazor.log exit 1 - - name: Instalar Chrome para Selenium - run: | - wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - - echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list - sudo apt-get update - sudo apt-get install -y google-chrome-stable - - name: Executar testes E2E env: WEB_BASE_URL: http://localhost:5000 diff --git a/BankMore/BankMore.sln b/BankMore/BankMore.sln index 721408a..819d2ad 100644 --- a/BankMore/BankMore.sln +++ b/BankMore/BankMore.sln @@ -47,10 +47,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankMore.Tarifas", "src\Ban EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankMore.Web", "src\BankMore.Web\BankMore.Web.csproj", "{506CA0C9-AAA5-4852-B43C-87B52FF7C87C}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NewFolder1", "NewFolder1", "{2719E7F0-5FF6-4A0E-ABFF-C55C317C840D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankMore.Web.E2ETests", "tests\BankMore.Web.E2ETests\BankMore.Web.E2ETests.csproj", "{D82733F6-5541-4733-97E7-162B246233DC}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -181,18 +177,6 @@ Global {506CA0C9-AAA5-4852-B43C-87B52FF7C87C}.Release|x64.Build.0 = Release|Any CPU {506CA0C9-AAA5-4852-B43C-87B52FF7C87C}.Release|x86.ActiveCfg = Release|Any CPU {506CA0C9-AAA5-4852-B43C-87B52FF7C87C}.Release|x86.Build.0 = Release|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Debug|x64.ActiveCfg = Debug|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Debug|x64.Build.0 = Debug|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Debug|x86.ActiveCfg = Debug|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Debug|x86.Build.0 = Debug|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Release|Any CPU.Build.0 = Release|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Release|x64.ActiveCfg = Release|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Release|x64.Build.0 = Release|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Release|x86.ActiveCfg = Release|Any CPU - {D82733F6-5541-4733-97E7-162B246233DC}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/BankMore/global.json b/BankMore/global.json deleted file mode 100644 index f7d8357..0000000 --- a/BankMore/global.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "sdk": { - "version": "10.0.101", - "rollForward": "latestFeature", - "allowPrerelease": false - } -} diff --git a/BankMore/tests/BankMore.Web.E2ETests/Infrastructure/SeleniumTestBase.cs b/BankMore/tests/BankMore.Web.E2ETests/Infrastructure/SeleniumTestBase.cs index 8a65bf8..aab3fbd 100644 --- a/BankMore/tests/BankMore.Web.E2ETests/Infrastructure/SeleniumTestBase.cs +++ b/BankMore/tests/BankMore.Web.E2ETests/Infrastructure/SeleniumTestBase.cs @@ -30,7 +30,7 @@ protected SeleniumTestBase() Wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10)); // URL base da aplicação (deve estar rodando no Docker) - BaseUrl = Environment.GetEnvironmentVariable("WEB_BASE_URL") ?? "http://localhost:5000"; + BaseUrl = Environment.GetEnvironmentVariable("WEB_BASE_URL") ?? "http://localhost:8080"; Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5); Driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(30); diff --git a/BankMore/tests/BankMore.Web.E2ETests/Tests/CadastroE2ETests.cs b/BankMore/tests/BankMore.Web.E2ETests/Tests/CadastroE2ETests.cs index d8b3505..5f85eb8 100644 --- a/BankMore/tests/BankMore.Web.E2ETests/Tests/CadastroE2ETests.cs +++ b/BankMore/tests/BankMore.Web.E2ETests/Tests/CadastroE2ETests.cs @@ -1,4 +1,4 @@ -using FluentAssertions; +using FluentAssertions; using BankMore.Web.E2ETests.Infrastructure; using BankMore.Web.E2ETests.PageObjects; @@ -27,9 +27,51 @@ public void DeveCarregarPaginaCadastro() Driver.Title.Should().Contain("Cadastro"); } + [Fact(DisplayName = "Deve criar conta com dados válidos")] + public void DeveCriarContaComDadosValidos() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "João Silva Teste E2E"; + var senha = "senha123"; + // Act + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + + // Assert + _cadastroPage.ExibeMensagemSucesso().Should().BeTrue(); + var mensagem = _cadastroPage.ObterMensagemSucesso(); + mensagem.Should().Contain("Conta criada com sucesso!"); + mensagem.Should().Contain("Número da conta:"); + + var numeroConta = _cadastroPage.ObterNumeroConta(); + numeroConta.Should().NotBeNullOrEmpty(); + numeroConta.Should().MatchRegex(@"^\d+$"); // Apenas números + } + + [Fact(DisplayName = "Deve redirecionar para login após cadastro bem-sucedido")] + public void DeveRedirecionarParaLoginAposCadastro() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Maria Teste Redirect"; + var senha = "senha456"; + + // Act + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + // Aguarda redirecionamento (2 segundos) + Thread.Sleep(2500); + // Assert + Driver.Url.Should().Contain("/login"); + } [Fact(DisplayName = "Deve exibir erro ao tentar criar conta com CPF inválido")] public void DeveExibirErroComCpfInvalido() @@ -50,7 +92,34 @@ public void DeveExibirErroComCpfInvalido() _cadastroPage.ObterMensagemErro().Should().NotBeNullOrEmpty(); } + [Fact(DisplayName = "Deve exibir erro ao tentar criar conta com CPF duplicado")] + public void DeveExibirErroComCpfDuplicado() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome1 = "Primeiro Cadastro"; + var nome2 = "Segundo Cadastro"; + var senha = "senha123"; + // Primeiro cadastro (sucesso) + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome1, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + _cadastroPage.ExibeMensagemSucesso().Should().BeTrue(); + + // Aguarda navegação + Thread.Sleep(2500); + + // Segundo cadastro com mesmo CPF (deve falhar) + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome2, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + + // Assert + _cadastroPage.ExibeMensagemErro().Should().BeTrue(); + } [Fact(DisplayName = "Deve desabilitar botão durante o loading")] public void DeveDesabilitarBotaoDuranteLoading() @@ -115,7 +184,7 @@ public void DeveAceitarCpfFormatado() // O importante é que não dê erro de javascript ou trave bool sucesso = _cadastroPage.ExibeMensagemSucesso(); bool erro = _cadastroPage.ExibeMensagemErro(); - + (sucesso || erro).Should().BeTrue("deve exibir alguma mensagem de feedback"); } diff --git a/BankMore/tests/BankMore.Web.E2ETests/Tests/LoginE2ETests.cs b/BankMore/tests/BankMore.Web.E2ETests/Tests/LoginE2ETests.cs index f10cad9..5f36cec 100644 --- a/BankMore/tests/BankMore.Web.E2ETests/Tests/LoginE2ETests.cs +++ b/BankMore/tests/BankMore.Web.E2ETests/Tests/LoginE2ETests.cs @@ -1,4 +1,4 @@ -using FluentAssertions; +using FluentAssertions; using BankMore.Web.E2ETests.Infrastructure; using BankMore.Web.E2ETests.PageObjects; @@ -29,9 +29,63 @@ public void DeveCarregarPaginaLogin() Driver.Title.Should().Contain("Login"); } - + [Fact(DisplayName = "Deve fazer login com credenciais válidas usando número da conta")] + public void DeveFazerLoginComNumeroContaValido() + { + // Arrange - Primeiro cria uma conta + var cpf = GerarCpfAleatorio(); + var nome = "Teste Login Conta"; + var senha = "senha123"; + + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + + var numeroConta = _cadastroPage.ObterNumeroConta(); + Thread.Sleep(2500); // Aguarda redirecionamento + + // Act - Faz login com o número da conta + _loginPage.NavigateToLogin(); + _loginPage.PreencherCredenciais(numeroConta, senha); + _loginPage.ClicarEntrar(); + _loginPage.AguardarLoadingDesaparecer(); + + // Assert + _loginPage.ExibeMensagemSucesso().Should().BeTrue(); + _loginPage.ObterMensagemSucesso().Should().Contain("Login realizado com sucesso!"); + + // Aguarda redirecionamento + Thread.Sleep(1000); + var url = Driver.Url; + (url.Contains("/conta") || url.Contains("/")).Should().BeTrue(); + } + + [Fact(DisplayName = "Deve fazer login com credenciais válidas usando CPF")] + public void DeveFazerLoginComCpfValido() + { + // Arrange - Primeiro cria uma conta + var cpf = GerarCpfAleatorio(); + var nome = "Teste Login CPF"; + var senha = "senha456"; + + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + Thread.Sleep(2500); + + // Act - Faz login com CPF + _loginPage.NavigateToLogin(); + _loginPage.PreencherCredenciais(cpf, senha); + _loginPage.ClicarEntrar(); + _loginPage.AguardarLoadingDesaparecer(); - + // Assert + _loginPage.ExibeMensagemSucesso().Should().BeTrue(); + Thread.Sleep(1000); + Driver.Url.Should().NotContain("/login"); + } [Fact(DisplayName = "Deve exibir erro com credenciais inválidas")] public void DeveExibirErroComCredenciaisInvalidas() @@ -52,7 +106,32 @@ public void DeveExibirErroComCredenciaisInvalidas() Driver.Url.Should().Contain("/login"); // Não deve redirecionar } - + [Fact(DisplayName = "Deve exibir erro com senha incorreta")] + public void DeveExibirErroComSenhaIncorreta() + { + // Arrange - Cria uma conta + var cpf = GerarCpfAleatorio(); + var nome = "Teste Senha Errada"; + var senhaCorreta = "senha123"; + var senhaErrada = "senhaerrada"; + + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senhaCorreta); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + var numeroConta = _cadastroPage.ObterNumeroConta(); + Thread.Sleep(2500); + + // Act - Tenta login com senha errada + _loginPage.NavigateToLogin(); + _loginPage.PreencherCredenciais(numeroConta, senhaErrada); + _loginPage.ClicarEntrar(); + _loginPage.AguardarLoadingDesaparecer(); + + // Assert + _loginPage.ExibeMensagemErro().Should().BeTrue(); + Driver.Url.Should().Contain("/login"); + } [Fact(DisplayName = "Deve desabilitar botão durante o loading")] public void DeveDesabilitarBotaoDuranteLoading() @@ -96,5 +175,100 @@ public void DeveValidarCamposObrigatorios() // Assert - formulário não deve submeter (validação HTML5) Driver.Url.Should().Contain("/login"); } - + + [Fact(DisplayName = "Deve redirecionar usuário autenticado para home")] + public void DeveRedirecionarUsuarioAutenticadoParaHome() + { + // Arrange - Cria conta e faz login + var cpf = GerarCpfAleatorio(); + var nome = "Teste Redirect Auth"; + var senha = "senha123"; + + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + var numeroConta = _cadastroPage.ObterNumeroConta(); + Thread.Sleep(2500); + + _loginPage.NavigateToLogin(); + _loginPage.PreencherCredenciais(numeroConta, senha); + _loginPage.ClicarEntrar(); + _loginPage.AguardarLoadingDesaparecer(); + Thread.Sleep(1000); + + // Act - Tenta acessar /login novamente + _loginPage.NavigateToLogin(); + Thread.Sleep(1000); + + // Assert - Deve ter sido redirecionado (se a lógica estiver implementada) + // Nota: Depende da implementação do OnInitialized no Login.razor + var url = _loginPage.ObterUrlAtual(); + (url.Contains("/conta") || url.Contains("/login")).Should().BeTrue(); + } + + [Fact(DisplayName = "Deve aceitar CPF ou número de conta no mesmo campo")] + public void DeveAceitarCpfOuNumeroContaNoMesmoCampo() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Teste Campo Único"; + var senha = "senha123"; + + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + var numeroConta = _cadastroPage.ObterNumeroConta(); + Thread.Sleep(2500); + + // Act & Assert - Login com CPF + _loginPage.NavigateToLogin(); + _loginPage.PreencherCredenciais(cpf, senha); + _loginPage.ClicarEntrar(); + _loginPage.AguardarLoadingDesaparecer(); + _loginPage.ExibeMensagemSucesso().Should().BeTrue(); + + ClearBrowserData(); + Thread.Sleep(1000); + + // Act & Assert - Login com número da conta + _loginPage.NavigateToLogin(); + _loginPage.PreencherCredenciais(numeroConta, senha); + _loginPage.ClicarEntrar(); + _loginPage.AguardarLoadingDesaparecer(); + _loginPage.ExibeMensagemSucesso().Should().BeTrue(); + } + + /// + /// Gera um CPF válido aleatório para testes + /// + private string GerarCpfAleatorio() + { + var random = new Random(); + var cpf = new int[11]; + + for (int i = 0; i < 9; i++) + { + cpf[i] = random.Next(0, 10); + } + + int soma = 0; + for (int i = 0; i < 9; i++) + { + soma += cpf[i] * (10 - i); + } + int resto = soma % 11; + cpf[9] = resto < 2 ? 0 : 11 - resto; + + soma = 0; + for (int i = 0; i < 10; i++) + { + soma += cpf[i] * (11 - i); + } + resto = soma % 11; + cpf[10] = resto < 2 ? 0 : 11 - resto; + + return string.Join("", cpf); + } } diff --git a/BankMore/tests/BankMore.Web.E2ETests/Tests/MinhaContaE2ETests.cs b/BankMore/tests/BankMore.Web.E2ETests/Tests/MinhaContaE2ETests.cs new file mode 100644 index 0000000..d8ce614 --- /dev/null +++ b/BankMore/tests/BankMore.Web.E2ETests/Tests/MinhaContaE2ETests.cs @@ -0,0 +1,274 @@ +using FluentAssertions; +using BankMore.Web.E2ETests.Infrastructure; +using BankMore.Web.E2ETests.PageObjects; + +namespace BankMore.Web.E2ETests.Tests; + +/// +/// Testes E2E para a página Minha Conta (após autenticação) +/// +public class MinhaContaE2ETests : SeleniumTestBase +{ + private CadastroPage _cadastroPage; + private LoginPage _loginPage; + private MinhaContaPage _minhaContaPage; + + public MinhaContaE2ETests() + { + _cadastroPage = new CadastroPage(Driver, this); + _loginPage = new LoginPage(Driver, this); + _minhaContaPage = new MinhaContaPage(Driver, this); + } + + [Fact(DisplayName = "Deve redirecionar para login quando não autenticado")] + public void DeveRedirecionarParaLoginQuandoNaoAutenticado() + { + // Arrange + ClearBrowserData(); // Garante que não há sessão + + // Act + _minhaContaPage.NavigateToMinhaConta(); + Thread.Sleep(1000); + + // Assert + _minhaContaPage.ExibeAlertaNaoAutenticado().Should().BeTrue(); + } + + [Fact(DisplayName = "Deve exibir dados da conta após login")] + public void DeveExibirDadosDaContaAposLogin() + { + // Arrange - Cria conta e faz login + var cpf = GerarCpfAleatorio(); + var nome = "João Silva Conta"; + var senha = "senha123"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + _minhaContaPage.ExibeDadosConta().Should().BeTrue(); + } + + [Fact(DisplayName = "Deve exibir número da conta correto")] + public void DeveExibirNumeroContaCorreto() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Maria Silva Numero"; + var senha = "senha456"; + + var numeroConta = CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + var numeroExibido = _minhaContaPage.ObterNumeroConta(); + numeroExibido.Should().Be(numeroConta); + } + + [Fact(DisplayName = "Deve exibir nome do titular correto")] + public void DeveExibirNomeCorreto() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Pedro Santos Nome"; + var senha = "senha789"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + var nomeExibido = _minhaContaPage.ObterNome(); + nomeExibido.Should().Contain(nome); + } + + [Fact(DisplayName = "Deve exibir CPF do titular")] + public void DeveExibirCpfCorreto() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Ana Costa CPF"; + var senha = "senha321"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + var cpfExibido = _minhaContaPage.ObterCpf(); + cpfExibido.Should().Contain(cpf.Substring(0, 3)); // Verifica se contém parte do CPF + } + + [Fact(DisplayName = "Deve exibir conta como ativa")] + public void DeveExibirContaComoAtiva() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Carlos Oliveira Status"; + var senha = "senha654"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + _minhaContaPage.ContaEstaAtiva().Should().BeTrue(); + _minhaContaPage.ObterStatus().Should().Contain("Ativa"); + } + + [Fact(DisplayName = "Deve exibir saldo da conta")] + public void DeveExibirSaldoDaConta() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Lucia Ferreira Saldo"; + var senha = "senha987"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + var saldo = _minhaContaPage.ObterSaldo(); + saldo.Should().NotBeNullOrEmpty(); + saldo.Should().Contain("R$"); // Formato monetário brasileiro + } + + [Fact(DisplayName = "Deve exibir saldo inicial zerado")] + public void DeveExibirSaldoInicialZerado() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Roberto Lima Saldo Zero"; + var senha = "senha111"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + var saldo = _minhaContaPage.ObterSaldo(); + saldo.Should().Contain("R$ 0,00"); + } + + [Fact(DisplayName = "Deve exibir página completa com todos os cards")] + public void DeveExibirPaginaCompletaComTodosOsCards() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Fernanda Souza Completo"; + var senha = "senha222"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + + // Assert + _minhaContaPage.ExibeDadosConta().Should().BeTrue(); + + // Verifica que consegue obter todos os dados principais + _minhaContaPage.ObterNome().Should().NotBeNullOrEmpty(); + _minhaContaPage.ObterCpf().Should().NotBeNullOrEmpty(); + _minhaContaPage.ObterStatus().Should().NotBeNullOrEmpty(); + _minhaContaPage.ObterSaldo().Should().NotBeNullOrEmpty(); + } + + [Fact(DisplayName = "Deve manter sessão ao navegar entre páginas")] + public void DeveManterSessaoAoNavegarEntrePaginas() + { + // Arrange + var cpf = GerarCpfAleatorio(); + var nome = "Gustavo Martins Sessao"; + var senha = "senha333"; + + CriarContaEFazerLogin(cpf, nome, senha); + + // Act - Navega para diferentes páginas + _minhaContaPage.NavigateToMinhaConta(); + _minhaContaPage.AguardarCarregamento(); + _minhaContaPage.ExibeDadosConta().Should().BeTrue(); + + NavigateTo("/transferencias"); + Thread.Sleep(1000); + + NavigateTo("/conta"); + _minhaContaPage.AguardarCarregamento(); + + // Assert - Ainda deve estar autenticado + _minhaContaPage.ExibeDadosConta().Should().BeTrue(); + } + + /// + /// Helper para criar conta e fazer login + /// + private string CriarContaEFazerLogin(string cpf, string nome, string senha) + { + // Cria a conta + _cadastroPage.NavigateToCadastro(); + _cadastroPage.PreencherFormulario(cpf, nome, senha); + _cadastroPage.ClicarCriarConta(); + _cadastroPage.AguardarLoadingDesaparecer(); + + var numeroConta = _cadastroPage.ObterNumeroConta(); + Thread.Sleep(2500); // Aguarda redirecionamento + + // Faz login + _loginPage.NavigateToLogin(); + _loginPage.PreencherCredenciais(numeroConta, senha); + _loginPage.ClicarEntrar(); + _loginPage.AguardarLoadingDesaparecer(); + Thread.Sleep(1000); + + return numeroConta; + } + + /// + /// Gera um CPF válido aleatório para testes + /// + private string GerarCpfAleatorio() + { + var random = new Random(); + var cpf = new int[11]; + + for (int i = 0; i < 9; i++) + { + cpf[i] = random.Next(0, 10); + } + + int soma = 0; + for (int i = 0; i < 9; i++) + { + soma += cpf[i] * (10 - i); + } + int resto = soma % 11; + cpf[9] = resto < 2 ? 0 : 11 - resto; + + soma = 0; + for (int i = 0; i < 10; i++) + { + soma += cpf[i] * (11 - i); + } + resto = soma % 11; + cpf[10] = resto < 2 ? 0 : 11 - resto; + + return string.Join("", cpf); + } +}