Skip to content

Commit

Permalink
Merge pull request #208 from nodlesh/feature/bcw-showcase-test-dev
Browse files Browse the repository at this point in the history
Feature/bc wallet with bc showcase automated tests
  • Loading branch information
nodlesh authored Nov 17, 2023
2 parents c1334db + 0c2de58 commit e6f24b7
Show file tree
Hide file tree
Showing 20 changed files with 816 additions and 5 deletions.
30 changes: 28 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ jobs:
- mobile-platform: "-p iOS"
app-file-name: "-a ${{ needs.check-app-updated.outputs.NEW_APP_NAME }}.ipa"
report-project: "bc-digital-id-ios"
- mobile-platform: "-p Android"
app-file-name: "-a ${{ needs.check-app-updated.outputs.NEW_APP_NAME }}.aab"
report-project: "bc-showcase-android"
- mobile-platform: "-p iOS"
app-file-name: "-a ${{ needs.check-app-updated.outputs.NEW_APP_NAME }}.ipa"
report-project: "bc-showcase-ios"
#timeout-minutes: 60
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -133,7 +139,7 @@ jobs:
DEVICE_CLOUD_KEY: "-k ${{ secrets.SAUCE_ACCESS_KEY }}"
MOBILE_PLATFORM: ${{ matrix.mobile-platform }}
APP_FILE_NAME: ${{ matrix.app-file-name }}
TEST_SCOPE: "-t @bc_wallet -t ~@wip -t ~@Connectionless -t ~@BCSC"
TEST_SCOPE: "-t @bc_wallet -t ~@wip -t ~@Connectionless -t ~@BCSC -t ~@BCShowcase"
REPORT_PROJECT: ${{ matrix.report-project }}
continue-on-error: true

Expand Down Expand Up @@ -161,7 +167,7 @@ jobs:
DEVICE_CLOUD_KEY: "-k ${{ secrets.SAUCE_ACCESS_KEY }}"
MOBILE_PLATFORM: ${{ matrix.mobile-platform }}
APP_FILE_NAME: ${{ matrix.app-file-name }}
TEST_SCOPE: "-t @bc_wallet -t @Connectionless -t ~@wip -t ~@BCSC"
TEST_SCOPE: "-t @bc_wallet -t @Connectionless -t ~@wip -t ~@BCSC -t ~@BCShowcase"
REPORT_PROJECT: ${{ matrix.report-project }}
continue-on-error: true

Expand Down Expand Up @@ -193,6 +199,26 @@ jobs:
REPORT_PROJECT: ${{ matrix.report-project }}
continue-on-error: true

- name: Run BC Wallet with BC Showcase Tests
if: ${{ contains(matrix.report-project,'bc-showcase') }}
uses: ./.github/workflows/run-test-harness
env:
LEDGER_URL_CONFIG: "http://test.bcovrin.vonx.io"
REGION: "us-west-1"
#TEST_RETRY_ATTEMPTS_OVERRIDE: "2"
with:
MOBILE_WALLET: "-w bc_wallet"
ISSUER_AGENT: '-i "BCShowcaseIssuer;https://bc-wallet-demo-dev.apps.silver.devops.gov.bc.ca/"'
VERIFIER_AGENT: '-v "BCShowcaseVerifier;https://bc-wallet-demo-dev.apps.silver.devops.gov.bc.ca/"'
DEVICE_CLOUD: "-d SauceLabs"
DEVICE_CLOUD_USER: "-u ${{ secrets.SAUCE_USERNAME }}"
DEVICE_CLOUD_KEY: "-k ${{ secrets.SAUCE_ACCESS_KEY }}"
MOBILE_PLATFORM: ${{ matrix.mobile-platform }}
APP_FILE_NAME: ${{ matrix.app-file-name }}
TEST_SCOPE: "-t @bc_wallet -t @BCShowcase -t ~@wip"
REPORT_PROJECT: ${{ matrix.report-project }}
continue-on-error: true

- name: Upload AMTH All Test results to Allure
uses: ./.github/workflows/run-send-gen-test-results-secure
with:
Expand Down
8 changes: 6 additions & 2 deletions aries-mobile-tests/agent_factory/agent_interface_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Factory class to create agent interface objects
given the agent type passed in.
"""
from agent_factory.bc_showcase.bc_showcase_issuer_agent_interface import BCShowcaseIssuerAgentInterface
from agent_factory.bc_showcase.bc_showcase_verifier_agent_interface import BCShowcaseVerifierAgentInterface
from agent_factory.issuer_agent_interface import IssuerAgentInterface
from agent_factory.verifier_agent_interface import VerifierAgentInterface
from agent_factory.aath.aath_issuer_agent_interface import AATHIssuerAgentInterface
Expand All @@ -16,11 +18,13 @@ class AgentInterfaceFactory():
issuer_agent_type_interface_dict = {
"AATH": AATHIssuerAgentInterface,
"CANdy_UVP": CANdy_UVP_IssuerAgentInterface,
"BC_VP": BC_VP_IssuerAgentInterface
"BC_VP": BC_VP_IssuerAgentInterface,
"BCShowcaseIssuer": BCShowcaseIssuerAgentInterface
}
verifier_agent_type_interface_dict = {
"AATH": AATHVerifierAgentInterface,
"BC_Person_Showcase": BCPersonShowcaseVerifierAgentInterface
"BC_Person_Showcase": BCPersonShowcaseVerifierAgentInterface,
"BCShowcaseVerifier": BCShowcaseVerifierAgentInterface
}

def create_issuer_agent_interface(self, agent_type, agent_endpoint) -> IssuerAgentInterface:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"""
Class for BC Showcase issuer agent for Student and Lawer Showcase Credentials
"""
import base64
import io
from agent_factory.issuer_agent_interface import IssuerAgentInterface
from sys import platform
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.core.os_manager import ChromeType
# import Page Objects needed
from agent_factory.bc_showcase.pageobjects.bc_wallet_showcase_main_page import BCWalletShowcaseMainPage
from agent_factory.bc_showcase.pageobjects.who_do_you_want_to_be_page import WhoDoYouWantToBePage
from agent_factory.bc_showcase.pageobjects.lets_get_started_page import LetsGetStartedPage
#from agent_factory.bc_showcase.pageobjects.going_digital_page import GoingDigitalPage

# Lawyer Showcase Page Objects
#from agent_factory.bc_showcase.pageobjects.accessing_court_materials_page import AccessingCourtMaterialsPage
#from agent_factory.bc_showcase.pageobjects.get_your_lawyer_credential_page import GetYourLawyerCredentialPage

# Student Showcase Page Objects
from agent_factory.bc_showcase.pageobjects.install_bc_wallet_page import InstallBCWalletPage
#from agent_factory.bc_showcase.pageobjects.connect_withbest_bc_college_page import ConnectWithBestBCCollegePage


class BCShowcaseIssuerAgentInterface(IssuerAgentInterface):

_actor : str
_bc_wallet_showcase_main_page: BCWalletShowcaseMainPage
_who_do_you_want_to_be_page: WhoDoYouWantToBePage
_lets_get_started_page: LetsGetStartedPage
_install_bc_wallet_page: InstallBCWalletPage
#_going_digital_page: GoingDigitalPage
#_accessing_court_materials_page: AccessingCourtMaterialsPage
#_get_your_lawyer_credential_page: GetYourLawyerCredentialPage
_install_bc_wallet_page: InstallBCWalletPage
#_connect_with_best_bc_college_page: ConnectWithBestBCCollegePage

def __init__(self, endpoint):
# Standup Selenuim Driver with endpoint
super().__init__(endpoint)
if platform == "linux" or platform == "linux2":
print("Starting Chromium on linux for BC Showcase Issuer Agent")
options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--headless")
self.driver = webdriver.Chrome(options=options, service=Service(ChromeDriverManager(chrome_type=ChromeType.CHROMIUM).install()))
else:
print("Starting Chrome on Mac or Windows for Issuer Agent")
self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# go to the issuer endpoint in the browser
self.driver.get(self.endpoint)
# instantiate intial page objects
self._bc_wallet_showcase_main_page = BCWalletShowcaseMainPage(self.driver)
# make sure we are on the first page, the terms of service page
if not self._bc_wallet_showcase_main_page.on_this_page():
raise Exception('Something is wrong, not on the BC Wallet Showcase Main Page')

def get_issuer_type(self) -> str:
"""return the type of issuer as a string BCShowcaseIssuer"""
return "BCShowcaseIssuer"

def create_invitation(self, oob=False, print_qrcode=False, save_qrcode=False, qr_code_border=40):
# This is not supported on the BC Showcase Issuer. Connection is made when sending the credential
# If called, send an exception back on this one and let the test handle it. Maybe a IssuerInterfaceFunctionNotSupported error.
return Exception('Function not supported for BC Showcase Issuer')

def connected(self):
"""return true if connected"""
# Check Issuing Credential Page for "Connected to the Issuer Agent"
return self._connect_with_best_bc_college_page.connected()


def send_credential(self, actor:str, credential_offer=None, version=1, schema=None, revokable=False):
"""send a credential to the holder, returns a qr code for holder to connect to"""
self._who_do_you_want_to_be_page = self._bc_wallet_showcase_main_page.select_get_started()
self.driver.minimize_window()
self.driver.maximize_window()
if actor == "Student":
self._who_do_you_want_to_be_page.select_student()
elif actor == "Lawyer":
self._who_do_you_want_to_be_page.select_lawyer()
else:
raise Exception(f"Unknown actor type {actor}")
self.driver.minimize_window()
self.driver.maximize_window()
self._lets_get_started_page = self._who_do_you_want_to_be_page.select_next()
self._install_bc_wallet_page = self._lets_get_started_page.select_next()
self._connect_with_best_bc_college_page = self._install_bc_wallet_page.select_skip()
self.driver.minimize_window()
self.driver.maximize_window()
qrcode = self._connect_with_best_bc_college_page.get_qr_code()

contents = qrcode.screenshot_as_base64.encode('utf-8')
return contents.decode('utf-8')


def revoke_credential(self, publish_immediately=True, notify_holder=False):
"""revoke a credential"""
return Exception('Function not supported for BC Showcase Issuer')
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
"""
Class for BC Showcase verifier agent for Student and Lawer Showcase Proofs
"""

from asyncio import sleep
from agent_factory.verifier_agent_interface import VerifierAgentInterface
from sys import platform
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.core.os_manager import ChromeType
import json
from agent_test_utils import get_qr_code_from_invitation
from agent_controller_client import agent_controller_GET, agent_controller_POST, expected_agent_state, setup_already_connected
# import Page Objects needed
from agent_factory.bc_showcase.pageobjects.bc_wallet_showcase_main_page import BCWalletShowcaseMainPage
from agent_factory.bc_showcase.pageobjects.who_do_you_want_to_be_page import WhoDoYouWantToBePage
from agent_factory.bc_showcase.pageobjects.lets_get_started_page import LetsGetStartedPage
from agent_factory.bc_showcase.pageobjects.install_bc_wallet_page import InstallBCWalletPage
from agent_factory.bc_showcase.pageobjects.connect_with_best_bc_college_page import ConnectWithBestBCCollegePage
from agent_factory.bc_showcase.pageobjects.youre_all_set_page import YoureAllSetPage
from agent_factory.bc_showcase.pageobjects.using_your_credentials_page import UsingYourCredentialsPage
from agent_factory.bc_showcase.pageobjects.getting_a_student_discount_page import GettingAStudentDiscountPage
from agent_factory.bc_showcase.pageobjects.start_proving_youre_a_student_page import StartProvingYoureAStudentPage
from agent_factory.bc_showcase.pageobjects.book_a_study_room_page import BookAStudyRoomPage
from agent_factory.bc_showcase.pageobjects.start_booking_the_room_page import StartBookingTheRoomPage

class BCShowcaseVerifierAgentInterface(VerifierAgentInterface):

_actor : str
_bc_wallet_showcase_main_page: BCWalletShowcaseMainPage
_who_do_you_want_to_be_page: WhoDoYouWantToBePage
_lets_get_started_page: LetsGetStartedPage
_install_bc_wallet_page: InstallBCWalletPage
_connect_with_best_bc_college_page: ConnectWithBestBCCollegePage
_youre_all_set_page: YoureAllSetPage
_using_your_credentials_page: UsingYourCredentialsPage

# Cool Clothes Online Page Objects
_getting_a_student_discount_page: GettingAStudentDiscountPage
_start_proving_youre_a_student_page: StartProvingYoureAStudentPage

# BestBC College Page Objects
_book_a_study_room_page: BookAStudyRoomPage
_start_booking_the_room_page: StartBookingTheRoomPage


def __init__(self, endpoint):
# Standup Selenuim Driver with endpoint
super().__init__(endpoint)
if platform == "linux" or platform == "linux2":
print("Starting Chromium on linux for BC Showcase Issuer Agent")
options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--headless")
self.driver = webdriver.Chrome(options=options, service=Service(ChromeDriverManager(chrome_type=ChromeType.CHROMIUM).install()))
else:
print("Starting Chrome on Mac or Windows for Issuer Agent")
self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# go to the issuer endpoint in the browser
self.driver.get(self.endpoint)
# instantiate intial page objects and navigate to the Proof portion of the BC Wallet Showcase
self._bc_wallet_showcase_main_page = BCWalletShowcaseMainPage(self.driver)

# make sure we are on the page for proofs in the Showcase.
if not self._bc_wallet_showcase_main_page.on_this_page():
raise Exception('Something is wrong, not on the BC Wallet Showcase Main Page')


def get_issuer_type(self) -> str:
"""return the type of issuer as a string BCShowcaseVerifier"""
return "BCShowcaseVerifier"

def create_invitation(self, oob=False, print_qrcode=False, save_qrcode=False, qr_code_border=40):
# This is not supported on the BC Showcase Verifier. Connection is made when sending the proof request
# If called, send an exception back on this one and let the test handle it. Maybe a VerifierInterfaceFunctionNotSupported error.
return Exception('Function not supported for BC Showcase Verifier')

def connected(self):
"""return True/False indicating if this issuer is connected to the wallet holder """
"""return true if connected"""
return self._connect_with_best_bc_college_page.connected()


def send_proof_request(self, actor:str, proof:str, version=1, request_for_proof=None, connectionless=False):
"""create a proof request """
self._who_do_you_want_to_be_page = self._bc_wallet_showcase_main_page.select_get_started()
self.driver.minimize_window()
self.driver.maximize_window()
if actor == "Student":
self._who_do_you_want_to_be_page.select_student()
elif actor == "Lawyer":
self._who_do_you_want_to_be_page.select_lawyer()
else:
raise Exception(f"Unknown actor type {actor}")
self.driver.minimize_window()
self.driver.maximize_window()
self._lets_get_started_page = self._who_do_you_want_to_be_page.select_next()
self._install_bc_wallet_page = self._lets_get_started_page.select_next()
self._connect_with_best_bc_college_page = self._install_bc_wallet_page.select_skip()
self.driver.minimize_window()
self.driver.maximize_window()
self._youre_all_set_page = self._connect_with_best_bc_college_page.select_i_already_have_my_credential()
self._using_your_credentials_page = self._youre_all_set_page.select_finish()

if proof == "Cool Clothes Online":
self._getting_a_student_discount_page = self._using_your_credentials_page.select_cool_clothes_online_start()
self.driver.minimize_window()
self.driver.maximize_window()
self._start_proving_youre_a_student_page = self._getting_a_student_discount_page.select_start()
self.driver.minimize_window()
self.driver.maximize_window()
qrcode = self._start_proving_youre_a_student_page.get_qr_code()
elif proof == "BestBC College":
self._book_a_study_room_page = self._using_your_credentials_page.select_bestbc_college_start()
self.driver.minimize_window()
self.driver.maximize_window()
self._start_booking_the_room_page = self._book_a_study_room_page.select_start()
self.driver.minimize_window()
self.driver.maximize_window()
qrcode = self._start_booking_the_room_page.get_qr_code()

contents = qrcode.screenshot_as_base64.encode('utf-8')
return contents.decode('utf-8')


def proof_success(self, proof_result):
if proof_result == "Discount":
return self._start_proving_youre_a_student_page.proof_success()
elif proof_result == "Room Booked":
return self._start_booking_the_room_page.proof_success()
elif proof_result == "Court Services":
pass
else:
raise Exception(f"Invalid proof result: {proof_result} expected Discount, Room Booked, or Court Services")
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from agent_factory.candy_uvp.pageobjects.webbasepage import WebBasePage
from selenium.webdriver.common.by import By
from pageobjects.basepage import WaitCondition
from agent_factory.bc_showcase.pageobjects.who_do_you_want_to_be_page import WhoDoYouWantToBePage

# These classes can inherit from a BasePage to do commone setup and functions
class BCWalletShowcaseMainPage(WebBasePage):
"""BC Wallet Showcase Main Entry page object"""

# Locators
on_this_page_text_locator = "BC Wallet Showcase"
#on_this_page_locator = (By.XPATH, '//*[@id="app"]/div/main/div/div/div/div[1]/div/div/h3[1]/strong')
#get_started_locator = (By.XPATH, '//button[@class='bg-bcgov-blue dark:bg-bcgov-white text-bcgov-white dark:text-bcgov-black py-3 px-5 rounded-lg font-semibold shadow-sm dark:shadow-none select-none ']')
get_started_locator = (By.CLASS_NAME, "bg-bcgov-blue")


def on_this_page(self):
#return super().on_this_page(self.on_this_page_locator, timeout=20)
return super().on_this_page(self.on_this_page_text_locator, timeout=20)

def select_get_started(self) -> WhoDoYouWantToBePage:
if self.on_this_page():
self.find_by(self.get_started_locator).click()
return WhoDoYouWantToBePage(self.driver)
else:
raise Exception(f"App not on the {type(self)} page")

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from PIL import Image
from agent_factory.candy_uvp.pageobjects.webbasepage import WebBasePage
from selenium.webdriver.common.by import By
from pageobjects.basepage import WaitCondition
import base64
from agent_factory.bc_showcase.pageobjects.start_booking_the_room_page import StartBookingTheRoomPage


# These classes can inherit from a BasePage to do commone setup and functions
class BookAStudyRoomPage(WebBasePage):
"""BC Wallet Showcase Book a Study Room page object"""

# Locators
on_this_page_text_locator = "needs a study room for some peace and quiet"
start_locator = (By.XPATH, "//button[normalize-space()='START']")

def on_this_page(self):
return super().on_this_page(self.on_this_page_text_locator)


def select_start(self) -> StartBookingTheRoomPage:
try:
self.find_by(self.start_locator, wait_condition=WaitCondition.ELEMENT_TO_BE_CLICKABLE).click()
except Exception as e:
if not self.on_this_page():
raise Exception(f"App not on the {type(self)} page")
else:
raise e
return StartBookingTheRoomPage(self.driver)
Loading

0 comments on commit e6f24b7

Please sign in to comment.