Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(misc): added the automation code for testing of docs #174

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CI

on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Python 3.10.4
uses: actions/setup-python@v2
with:
python-version: 3.10.4

- name: Installing package list
run: apt list --installed

- name: Removing previous chrome instances on runner
run: sudo apt purge google-chrome-stable

- name: Install xvfb
run: sudo apt-get install xvfb

- name: Install copy paste mechanism
run: sudo apt-get install xsel

- name: Create virtual environment
run: python -m venv venv

- name: Activate virtual environment
run: source venv/bin/activate

- name: Install dependencies
run: |
pip install --upgrade pip
pip install selenium uagents pyperclip pytest psutil undetected-chromedriver chromedriver-autoinstaller PyVirtualDisplay

- name: Run your tests
run: |
python -m pytest tests/automation_tests.py
Empty file added tests/__init__.py
Empty file.
205 changes: 205 additions & 0 deletions tests/automation_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import time
import subprocess
import pytest
import pyperclip
from selenium.webdriver.common.by import By
import tempfile
import os
import socket
import psutil


def terminate_process_by_port(port):
for proc in psutil.process_iter(attrs=["pid", "name"]):
try:
connections = proc.connections()
for conn in connections:
if conn.laddr.port == port:
print(f"Terminating process {proc.pid} using port {port}")
process = psutil.Process(proc.pid)
process.terminate()
process.wait()
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass


@pytest.mark.usefixtures("setup")
class TestFetchAgents:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm a bit confused, probably needs some discussion; it looks like you're building a unit test per a test per a code block; you're building the website and then getting selenium to hit the copy button, after that you create a file with the python code, and run it with popen.

This of course would work, but feels really wrong 😅 In the short term, could you not iterate over all docs files, looking for python code blocks, and then re-use the logic for popen of the copied string? and test response on that?

I think after this, we'd look to have dedicated unit tests for each code block, but that is involved.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there might have been some misunderstanding, i though we have discussed to test the code blocks directly through the website using selenium.

can you please share what could go wrong with the current approach? since we will have to include the test cases for the individual files manually whenever there is new code block, i guess the either approach will behave the same?

Although, i have shared you the list of approaches to you in the personal message, what you are saying is there in the second point. can you please verify the approach?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if there has been a misunderstanding, and you're right to have gone forward without some clear direction from me :) I get a lot of messages and some things slip by 👎

There isn't something wrong with this, I just think booting up the site, and running selenium is excessive.

def test_creating_yeour_first_uAgent(self):
print("copy")
copy_button = self.driver.find_elements(
By.XPATH, "//button[@title='Copy code']"
)
for i in range(len(copy_button)):
if i == 2:
copy_button[i].click()
time.sleep(3)
fist_uagent = pyperclip.paste()
with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, "temp_script.py")
with open(temp_file_path, "w") as temp_file:
print("write")
temp_file.write(fist_uagent)
result = subprocess.Popen(
["python", temp_file_path, "--port", "8000"])
print("Python script output:")
print(result.stdout)
time.sleep(6)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
results = sock.connect_ex(("localhost", 8000))
if results == 0:
assert True
terminate_process_by_port(8000)
else:
assert False
print("Port 8000 is not in use.")

def test_Creating_an_interval_task(self):
self.driver.find_element(
By.XPATH, "//a[text()='Creating an interval task'][1]"
).click()
copy_button = self.driver.find_elements(
By.XPATH, "//button[@title='Copy code']"
)
for i in range(len(copy_button)):
if i == 2:
copy_button[i].click()
time.sleep(3)
interval_task = pyperclip.paste()

with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, "temp_script.py")
with open(temp_file_path, "w") as temp_file:
temp_file.write(interval_task)
result = subprocess.Popen(
["python", temp_file_path, "--port", "8000"])
print("Python script output:")
print(result.stdout)
time.sleep(6)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
results = sock.connect_ex(("localhost", 8000))
if results == 0:
assert True
terminate_process_by_port(8000)
else:
assert False
print("Port 8000 is not in use.")

def test_Getting_uAgent_addresses(self):
self.driver.find_element(
By.XPATH, "//a[text()='Getting uAgent addresses 🤖📫'][1]"
).click()
copy_button = self.driver.find_elements(
By.XPATH, "//button[@title='Copy code']"
)
for i in range(len(copy_button)):
if i == 4:
copy_button[i].click()
time.sleep(3)
address = pyperclip.paste()
with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, "temp_script.py")
with open(temp_file_path, "w") as temp_file:
temp_file.write(address)
result = subprocess.Popen(
["python", temp_file_path, "--port", "8000"])
print("Python script output:")
print(result.stdout)
time.sleep(6)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
results = sock.connect_ex(("localhost", 8000))
if results == 0:
assert True
terminate_process_by_port(8000)
else:
assert False
print("Port 8000 is not in use.")

def test_registering_in_the_Almanac_Contract(self):
self.driver.find_element(
By.XPATH, "//a[text()='Registering in the Almanac Contract'][1]"
).click()
self.driver.find_element(
By.XPATH, "//button[@title='Copy code']").click()
time.sleep(3)
contract = pyperclip.paste()
with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, "temp_script.py")
with open(temp_file_path, "w") as temp_file:
temp_file.write(contract)
result = subprocess.Popen(
["python", temp_file_path, "--port", "8000"])
print("Python script output:")
print(result.stdout)
time.sleep(6)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
results = sock.connect_ex(("localhost", 8000))
if results == 0:
assert True
terminate_process_by_port(8000)

def test_communicating_with_other_uAgents1(self):
self.driver.find_element(
By.XPATH, "//a[text()='Communicating with other uAgents 📱🤖️'][1]"
).click()
time.sleep(2)
copy_button = self.driver.find_elements(
By.XPATH, "//button[@title='Copy code']"
)
for i in range(len(copy_button)):
if i == 5:
copy_button[i].click()
time.sleep(4)
agents_communication = pyperclip.paste()

with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, "temp_script.py")
with open(temp_file_path, "w") as temp_file:
temp_file.write(agents_communication)
result = subprocess.Popen(
["python", temp_file_path, "--port", "8000"])
print("Python script output:")
print(result.stdout)
time.sleep(9)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
results = sock.connect_ex(("localhost", 8000))
if results == 0:
assert True
terminate_process_by_port(8000)
time.sleep(3)
else:
assert False
print("Port 8000 is not in use.")

def test_communicating_with_other_uAgents2(self):
self.driver.find_element(
By.XPATH, "//a[text()='Communicating with other uAgents 📱🤖️'][1]"
).click()
time.sleep(2)
copy_button = self.driver.find_elements(
By.XPATH, "//button[@title='Copy code']"
)
for i in range(len(copy_button)):
if i == 10:
copy_button[i].click()
time.sleep(4)
remote_agents_alice = pyperclip.paste()

with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, "temp_script.py")
with open(temp_file_path, "w") as temp_file:
temp_file.write(remote_agents_alice)
result = subprocess.Popen(
["python", temp_file_path, "--port", "8000"])
print("Python script output:")
print(result.stdout)
time.sleep(9)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
results = sock.connect_ex(("localhost", 8000))
if results == 0:
assert True
terminate_process_by_port(8000)
time.sleep(3)
else:
assert False
print("Port 8000 is not in use.")
30 changes: 30 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from selenium import webdriver
import time
import pytest
import chromedriver_autoinstaller
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800, 800))
display.start()

chromedriver_autoinstaller.install()


chrome_options = webdriver.ChromeOptions()
options = [
"--window-size=1200,1200",
"--ignore-certificate-errors"
]

for option in options:
chrome_options.add_argument(option)


@pytest.fixture(scope="class")
def setup(request):
request.cls.driver = webdriver.Chrome(options=chrome_options)
request.cls.driver.get(
'https://fetch.ai/docs/guides/agents/create-a-uagent')
request.cls.driver.maximize_window()
time.sleep(2)
yield
request.cls.driver.quit()
Loading