//
//  AdvancedSignUpPasswordAutofillTests.swift
//  BeamUITests
//
//  Created by Quentin Valero on 11/05/2022.
//

import Foundation
import XCTest

class AdvancedSignUpPasswordAutofillTests: BaseTest {

    let alertView = AlertTestView()
    let firstName = "Jean"
    let lastName = "Martin"
    let phone = "0123456789"
    let gender = "Gender"
    let day = "01"
    let month = "February"
    let year = "2000"
    let view = "Sign Up"
    let loginUsername = "signin.form"
    let loginEmail = "signin.form@email.beam"
    let securedAutoCompletedPassword = "••••••••••••••••••••"
    let timeout = 0.5
    var generatedPassword = "password"

    override func setUp() {
        super.setUp()
        uiMenu.invoke(.startMockHttpServer)
            .invoke(.populatePasswordsDB)
    }

    private func verifyPwManagerNotDisplayedDropdown(field: String, data: String) {
        step("When I click on \(field) field") {
            mockPage.getDropdownFieldElement(title: field, inView: view).clickOnExistence()
        }
        
        step("Then password manager is not displayed") {
            XCTAssertFalse(passwordManagerHelper.doesAutofillPopupExist(autofillText: loginUsername))
            XCTAssertFalse(passwordManagerHelper.doesOtherPasswordsPopupExist())
        }
    }
    
    private func verifyPwManagerNotDisplayedTextField(field: String, data: String) {
        step("When I click on \(field) field") {
            mockPage.getUsernameFieldElement(title: field, inView: view).clickOnExistence()
        }
        
        step("Then password manager is not displayed") {
            XCTAssertFalse(passwordManagerHelper.doesAutofillPopupExist(autofillText: loginUsername))
            XCTAssertFalse(passwordManagerHelper.doesOtherPasswordsPopupExist())
        }
    }
    
    private func fillDataWithoutPwManager(field: String, data: String) {
        step("When I click on \(field) field") {
            mockPage.getUsernameFieldElement(title: field, inView: view).clickOnExistence()
        }
        
        step("Then password manager is not displayed") {
            XCTAssertFalse(passwordManagerHelper.doesAutofillPopupExist(autofillText: loginUsername))
            XCTAssertFalse(passwordManagerHelper.doesOtherPasswordsPopupExist())
            mockPage.getUsernameFieldElement(title: field, inView: view).clickClearAndType(data)
            mockPage.typeKeyboardKey(.escape) // In case of autocomplete
        }
    }
    
    private func fillPasswordFieldWithSuggestedPassword(field: String = "Password: ") {
        step("When I click on Password field") {
            mockPage.getPasswordFieldElement(title: field, inView: view).clickOnExistence()
        }
        
        step("Then password manager is displayed") {
            XCTAssertFalse(passwordManagerHelper.doesAutofillPopupExist(autofillText: loginEmail))
            XCTAssertFalse(passwordManagerHelper.doesOtherPasswordsPopupExist())
            XCTAssertTrue(passwordManagerHelper.doesAutogeneratedPasswordPopupExist())
            generatedPassword = mockPage.getPasswordElementWithValue(title: field, inView: view).getStringValue()
            passwordManagerHelper.useAutogeneratedPassword()
        }
    }
    
    func testSignUpPageCombination1() {
        testrailId("C860")
        step("Given I navigate to \(mockPage.getMockPageUrl(.signup1Form))") {
            mockPage.openMockPage(.signup1Form)
        }
        
        verifyPwManagerNotDisplayedTextField(field: "First Name: ", data: firstName)
        verifyPwManagerNotDisplayedTextField(field: "Last Name: ", data: lastName)
        fillDataWithoutPwManager(field: "Username: ", data: loginUsername)
        fillPasswordFieldWithSuggestedPassword()
        verifyPwManagerNotDisplayedTextField(field: "Phone: ", data: phone)
        verifyPwManagerNotDisplayedTextField(field: "Gender: ", data: gender)
        verifyPwManagerNotDisplayedDropdown(field: "Month: ", data: month)
        verifyPwManagerNotDisplayedTextField(field: "Day: ", data: day)
        verifyPwManagerNotDisplayedTextField(field: "Year: ", data: year)
        
        
        step("When I submit the form") {
            mockPage.getContinueButtonElement(inView: view).clickOnExistence()
        }
        
        step("Then the result page is populated with sign up data") {
            alertView.notNowClick() // will fail if pop up is not displayed
            XCTAssertEqual(mockPage.getResultValue(label: "username"), loginUsername)
            XCTAssertEqual(mockPage.getResultValue(label: "password"), generatedPassword)
        }
    }
    
    func testSignUpPageCombination2() {
        testrailId("C861")
        step("Given I navigate to \(mockPage.getMockPageUrl(.signup2Form))") {
            mockPage.openMockPage(.signup2Form)
        }
        
        verifyPwManagerNotDisplayedTextField(field: "First Name: ", data: firstName)
        verifyPwManagerNotDisplayedTextField(field: "Last Name: ", data: lastName)
        fillDataWithoutPwManager(field: "Email: ", data: loginEmail)
        fillPasswordFieldWithSuggestedPassword()
        verifyPwManagerNotDisplayedTextField(field: "Phone: ", data: phone)
        verifyPwManagerNotDisplayedTextField(field: "Gender: ", data: gender)
        verifyPwManagerNotDisplayedDropdown(field: "Month: ", data: month)
        verifyPwManagerNotDisplayedTextField(field: "Day: ", data: day)
        verifyPwManagerNotDisplayedTextField(field: "Year: ", data: year)
        
        
        step("When I submit the form") {
            mockPage.getContinueButtonElement(inView: view).clickOnExistence()
        }
        
        step("Then the result page is populated with sign up data") {
            alertView.notNowClick() // will fail if pop up is not displayed
            XCTAssertEqual(mockPage.getResultValue(label: "email"), loginEmail)
            XCTAssertEqual(mockPage.getResultValue(label: "password"), generatedPassword)
        }
    }
    
    func testSignUpPageCombination3() {
        testrailId("C862")
        step("Given I navigate to \(mockPage.getMockPageUrl(.signup3Form))") {
            mockPage.openMockPage(.signup3Form)
        }
        
        verifyPwManagerNotDisplayedTextField(field: "Phone: ", data: phone)
        fillDataWithoutPwManager(field: "Email: ", data: loginEmail)
        fillDataWithoutPwManager(field: "Confirm Email: ", data: loginEmail)
        verifyPwManagerNotDisplayedTextField(field: "Birthdate: ", data: year)
        fillPasswordFieldWithSuggestedPassword()
        
        step("When I submit the form") {
            mockPage.getContinueButtonElement(inView: view).clickOnExistence()
        }
        
        step("Then the result page is populated with sign up data") {
            alertView.notNowClick() // will fail if pop up is not displayed
            XCTAssertEqual(mockPage.getResultValue(label: "email"), loginEmail)
            XCTAssertEqual(mockPage.getResultValue(label: "password"), generatedPassword)
        }
    }
    
    func testSignUpPageCombination4() {
        testrailId("C863")
        step("Given I navigate to \(mockPage.getMockPageUrl(.signup4Form))") {
            mockPage.openMockPage(.signup4Form)
        }
        
        verifyPwManagerNotDisplayedTextField(field: "First Name: ", data: firstName)
        verifyPwManagerNotDisplayedTextField(field: "Last Name: ", data: lastName)
        verifyPwManagerNotDisplayedTextField(field: "Birthdate: ", data: year)
        fillDataWithoutPwManager(field: "Email: ", data: loginEmail)
        fillPasswordFieldWithSuggestedPassword()
        XCTAssertEqual(mockPage.getPasswordFieldElement(title: "Confirm Password: ", inView: view).getStringValue(), securedAutoCompletedPassword)
        
        step("When I submit the form") {
            mockPage.getContinueButtonElement(inView: view).clickOnExistence()
        }
        
        step("Then the result page is populated with sign up data") {
            alertView.notNowClick() // will fail if pop up is not displayed
            XCTAssertEqual(mockPage.getResultValue(label: "subscriptionEmail"), loginEmail)
            XCTAssertEqual(mockPage.getResultValue(label: "subscriptionPassword"), generatedPassword)
            XCTAssertEqual(mockPage.getResultValue(label: "subscriptionPasswordConfirmation"), generatedPassword)

        }
    }
    
    func testSignUpPageCombination5() {
        testrailId("C864")
        step("Given I navigate to \(mockPage.getMockPageUrl(.signup51Form))") {
            mockPage.openMockPage(.signup51Form)
        }
        
        fillDataWithoutPwManager(field: "Email: ", data: loginEmail)
        mockPage.getContinueButtonElement(inView: view).clickOnExistence()
        verifyPwManagerNotDisplayedTextField(field: "Username: ", data: firstName)
        fillPasswordFieldWithSuggestedPassword()
        
        step("When I submit the form") {
            mockPage.getContinueButtonElement(inView: view).clickOnExistence()
        }
        
        step("Then the result page is populated with sign up data") {
            alertView.notNowClick() // will fail if pop up is not displayed
            XCTAssertEqual(mockPage.getResultValue(label: "email"), loginEmail)
            XCTAssertEqual(mockPage.getResultValue(label: "password"), generatedPassword)
        }
    }
    
    func testSignUpPageCombination6() {
        testrailId("C865")
        step("Given I navigate to \(mockPage.getMockPageUrl(.signup6Form))") {
            mockPage.openMockPage(.signup6Form)
        }
        
        verifyPwManagerNotDisplayedTextField(field: "Name: ", data: firstName)
        fillDataWithoutPwManager(field: "Email: ", data: loginEmail)
        fillPasswordFieldWithSuggestedPassword()
        
        step("When I submit the form") {
            mockPage.getContinueButtonElement(inView: view).clickOnExistence()
        }
        
        step("Then the result page is populated with sign up data") {
            alertView.notNowClick() // will fail if pop up is not displayed
            XCTAssertEqual(mockPage.getResultValue(label: "email"), loginEmail)
            XCTAssertEqual(mockPage.getResultValue(label: "password"), generatedPassword)
        }
    }
    
}
        
