Skip to content
Merged
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
Binary file modified .DS_Store
Binary file not shown.
39 changes: 38 additions & 1 deletion guideframe/selenium.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def driver_setup(driver_location):
# Function to open a URL
def open_url(driver, target):
driver.get(target)
sleep(2) # Give the page time to load
# sleep(1) # Give the page time to load


# Function to set window size
Expand Down Expand Up @@ -169,6 +169,7 @@ def take_screenshot(driver, file_name="screenshot.png"):
print(f"Error taking screenshot: {e}")
raise


# Function to select a dropdown option by visible text
def select_dropdown_option(driver, dropdown_id, visible_text):
try:
Expand All @@ -194,3 +195,39 @@ def click_button_by_span_text(driver, span_text):
except Exception as e:
print(f"Error clicking button with span text '{span_text}': {e}")
raise


# Function to click an element by its XPath
def click_element_by_xpath(driver, xpath):
try:
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, xpath))
)
element.click()
except Exception as e:
print(f"Error clicking element with xpath '{xpath}': {e}")
raise


# Function to hover over an element by its XPath
def hover_over_element_by_xpath(driver, xpath):
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, xpath))
)
actions = ActionChains(driver)
actions.move_to_element(element).perform()
except Exception as e:
print(f"Error hovering over element with xpath '{xpath}': {e}")
raise


# Function to highlight code on GitHub.com (useful for code walkthroughs)
def highlight_github_code(driver, target):
driver.get(target)
driver.refresh() # Refresh the page to ensure the code is highlighted


# Function to sleep for a specified number of seconds (added to negate the need to import time)
def sleep_for(seconds):
sleep(seconds)
4 changes: 2 additions & 2 deletions guideframe/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ def guide_step(step_number, *actions, order="action-after-vo"):
if order == "action-before-vo":
for action in actions:
action()
time.sleep(1)
# time.sleep(1)
generate_voicover(md_file, step_number)
else: # Default order is action-after-vo
generate_voicover(md_file, step_number)
for action in actions:
action()
time.sleep(1)
# time.sleep(1)

stop_ffmpeg_recording(step)
89 changes: 89 additions & 0 deletions guideframe_code_demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
## Step 1
Guide-Frame is a tool which allows software engineers to generate walkthrough videos using python. This demo aims to illustrate the functionality of Guide-Frame by examining its codebase. Before we dive into the underlying logic, lets first examine a Guide-Frame script in order to provide some broader context.

## Step 2
The selenium functions demo will serve as an example of a GuideFrame script. Each script is a python file and must also have a markdown file with a matching name. Let's briefly touch on the format and role of this markdown file.

## Step 3
GuideFrame creates the voiceover based on this markdown file. It simply requires a user to create a ## heading with the text 'Step Number'. Under this heading, the user can add whatever text corresponds to the actions they define in the main GuideFrame script. This promotes ease of adjustment in the event of purely audio changes. Lets switch back to the main script and run through some of the setup syntax.

## Step 4
All the python script requires is the relevant imports as seen at the top of the file. A user should then define a guideframe script function, as seen here on line 7. After some initial environment setup, via the functions imported from the GuideFrame package, a user can start defining their GuideFrame steps.

## Step 5
Let's examine steps 1 and 2 to illustrate the syntax of a GuideFrame step. Each step takes a number as an argument in addition to a lambda function and an opptional argument for the order of the voicever relative to the interactions. In the case of step 1, lambda is set to none in order to hang on the main webpage while the voiceover is performed. Step 2 features a call to the click button by span text function to click the agree button.

## Step 6
Lets skip to step 14 to demonstrate the ability to pass multiple actions. In this case, we're filling review fields on the test site. A user can pass as many actions to a step as they wish and GuideFrame will iterate them.

## Step 7
Once a user has defined all of their guide steps within a function, they can simply call this function within main. The user should then pass the number of steps to the assemble function from the GuideFrame library. This function carries out the assembly of all generated audio and video segments. Now that we've got a high level understanding of GuideFrame, let's take a look at the underlying code.

## Step 8
Let's start off by examining one of the selenium functions. The selenium file acts as an SDK which allows user's to more easily create individual interactions. There are numerous actions available but for this demonstration we'll use a small subset. The first one we'll look at is the open link in new tab function. Like many of these functions, its wrapped in a try block with exception handling. This ensures any failures propagate up to the GitHub action. The function takes the webdriver and a h ref as an argument. The h ref is then passed to selenium's native functions. It opens the link and then switches to the most recently opened tab.

## Step 9
Lets demonstrate it by using the magento test site. We'll use the function to open the test site in a new tab and switch to it.

## Step 10
The click element function takes a driver and a C S S selector as arguments. It uses selenium's functionality to wait for the element to appear and then clicks on it.

## Step 11
Let's return to the test site to demonstrate that. In this case we'll click on the sign in button.

## Step 12
The type into field function takes the driver, element i d and text as arguments. It uses seleniums ability to pass text into form fields to achieve its purpose.

## Step 13
Let's switch back to magento to see it in action. In this case we can fill the login details. We achieve this by using two different functions within one guide step.

## Step 14
The final function we'll examine allows a user to hover over elements. This function takes a h ref as an argument. It uses selenium's action chains to move to the h ref's element.

## Step 15
When defining this particular step, we also pass sleep functions to allow space between selections.

## Step 16
Now that we've demonstrated some of the functions, lets dive a little deeper into the core logic that makes this possible. The utils file contains much of the logic relating to the guide steps themselves. The function seen here uses script arguments to assign appropriate variables.

## Step 17
This pair of functions simply serve to extract the scripts name for use in additional logic.

## Step 18
The guide step function orchestrates much of the core logic via calls to various functions. It extracts environment data and then passes this to f f m peg to begin a screen recording. It then checks the order variable and loops through the actions passed as arguments. The generate voiceover function is then called based on the order. This takes the step number and markdown file in order to pull the text from its match. Finally, the function ends by stopping the f f m peg recording.

## Step 19
Much of the remaining logic should be relatively clear. Within the audio file, regex is used to extract the text under the markdown headings. This is then passed to the generate voiceover function. This uses g t t s to create the audio clip. Finally, an additional function sleeps based on the length of this audio clip. This ensures that interactions don't occur until a voiceover segment is complete.

## Step 20
The video file simply contains the functions called in the guide steps. They start and stop f f mpeg, taking the environment variables previously mentioned.

## Step 21
The assembly file is where the audio and video segments for each step are combined. This first function checks for the existence of the matching audio and video files. f f m peg is then used to combine them into a single video with voiceover.

## Step 22
The combine all videos function takes the output files and a name as arguments. It then writes these to a text file. This list of files is then passed to f f m peg for concatination. The final file name is dictated by the second function argument.

## Step 23
The assemble function takes the steps number and uses it to loop through all of the created files. It then passes these to the assemble audio video function mentioned earlier. It then creates the required name and an array based on the combined files. Both the array and filename are then passed to the combine all videos function.

## Step 24
Finally, a cleanup loop removes all of the files generated through this process.

## Step 25
The final layer of guideframe is its use as a git hub action. This allows users to run guideframe on repository updates in order to ensure new render on changes. This removes the need for local rendering by an engineer. It also ensures that breaking changes to guideframe or the product it demos are easily caught.

## Step 26
This render workflow activates on push events. It spins up an ubuntu git hub runner and installs the requirements needed to run guideframe. The pip install commands here don't install the guideframe package. This is because this workflow runs within the source repository. Within the template repository, these python installations are replaced with pip install guideframe.

## Step 27
Once the environment is set up, the virtual display is started. The tutors test is then run before a final step uploads this output as an artifact. This allows the user to download the final mp4 from the workflow. This then completes the full GuideFrame pipeline.

## Step 28
This concludes the walkthrough. Be sure to check out the project on GitHub or PyPy.






Loading