TestProject Forum
Powered by leading experts in the test automation community

Interaction between 2 devices based on QR code

Hi,
I want to setup the following test scenario with 2 physical devices:
Step 1. Mobile device A (iOS) shows a randomly created device QR code on its screen
Step 2. Mobile device B (android), which is physically located in front of device A, opens a scanner and scans the QR code from device A
Step 3. Mobile device B interpretes the QR code and shows the information in a new screen

What do I need for this? Concurring tests? If yes, how can I align these tests?

Hello,

You will need to create two jobs, one for the test that creates the QR code on the screen of device A, and another for the test that scans the code from the screen of the first device, this is due to jobs being segregated to Web,Android and iOS jobs respectively.

You can then schedule these jobs to run at certain times or execute them both manually through the UI, one after another, or you can do so via our RESTful API and a script.

You can use this Python script, and replace the parameters with ones from the relevant project and jobs, as well as your API key:

import requests
from threading import Timer
import time
import datetime

project_id = "PROJECT_ID"
base = "https://api.testproject.io"
header = {"Authorization": "YOUR_API_KEY"}
jobs_ids = ["JOB1_ID", "JOB2_ID"]
jobs_names = {}
executions_id = {}
interval = 120  # Interval in seconds, set it to your liking.
job_states = ["Failed", "Passed", "Skipped", "Suspended", "Error", "Aborted"]
summary = {}
starting_times = {}
body = {"queue": "true"}
counter = 0


def execute_job():
    for job_id in jobs_ids:
        url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/run"
        response = requests.post(url, headers=header, data=body)
        job_name = jobs_names[job_id]
        try:
            data = response.json()
            if 'id' in data:
                print(f"Starting '{job_name}' ...")
                executions_id[job_id] = data['id']
        except:
            print(f"Job '{job_name}' can not execute, status code is {response.status_code}.")
        time.sleep(5)


def reset_starting_times():
    for job_name in jobs_names.values():
        starting_times[job_name] = None


def get_state_with_timer(job_id, execution_id):
    global counter
    url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/executions/{execution_id}/state"
    state = requests.get(url, headers=header)
    job_name = get_job_name(job_id)
    t = Timer(interval, get_state_with_timer, [job_id, execution_id])
    t.start()
    data = state.json()
    state_result = data['state']
    if state_result == "Executing" and starting_times[job_name] == None:
        starting_times[job_name] = datetime.datetime.now()
    print(f"Job: {job_name}, State: {state_result}")
    # Checking interval countdown --
    counter += 1
    if counter == len(jobs_ids):
        print("-----------------------------")
        counter = 0
    # Checking interval countdown --
    if state_result in job_states:
        t.cancel()
        summary[job_name] = state_result
        if len(summary) == len(executions_id):
            show_summary()


def get_jobs_names():
    for job_id in jobs_ids:
        jobs_names[job_id] = get_job_name(job_id)


def get_state(job_id, execution_id):
    url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/executions/{execution_id}/state"
    state = requests.get(url, headers=header)
    try:
        return state.json()['state']
    except:
        print(f"Can not retrieve status, status code is {state.status_code}.")


def start_interval():
    for job_id, execution_id in executions_id.items():
        get_state_with_timer(job_id, execution_id)


def get_job_name(job_id):
    url = f"{base}/v2/projects/{project_id}/jobs/{job_id}/"
    response = requests.get(url, headers=header)
    try:
        return response.json()['name']
    except:
        print(f"Could not retrieve Job name, status code is {response.status_code}.")


def show_summary():
    print("\nSummary:\n")
    for job_name, final_state in summary.items():
        print(f"Job \'{job_name}\' has finished with the result of: {final_state}")
        print(
            f"Executed on {starting_times[job_name]} {time.tzname}, with the execution time of: {datetime.datetime.now() - starting_times[job_name]}\n")


get_jobs_names()
reset_starting_times()
execute_job()  # Start executing jobs

Okay, thank you very much. I’ll give it a try!