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

System test with robot framework #8481

Merged
merged 101 commits into from
Jul 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
f868f5f
WIP prototype sysTest
feerrenrut May 16, 2018
e9a2af7
WIP include flaky way of exiting
feerrenrut May 16, 2018
1fb27cb
WIP System testing
feerrenrut May 17, 2018
584ea96
Merge branch 'master' into systemTestWithRobot
michaelDCurran Jun 7, 2018
5c83124
First try at including system tests in appveyor.
michaelDCurran Jun 7, 2018
dd9f3e7
Disable pyAutoGUI's failsafe check as appeyor moves the mouse???
michaelDCurran Jun 7, 2018
5a75207
Merge branch 'systemTestWithRobot' into appveyorTests
michaelDCurran Jun 7, 2018
1e6e265
initial.robot: break robot to temporarily bipass freeze.
michaelDCurran Jun 7, 2018
69f4407
appveyor.yaml: run robot in powershell so exit code is ignored for now.
michaelDCurran Jun 7, 2018
9bd9760
appveyor.yaml: try again to make system tests return error code 0
michaelDCurran Jun 7, 2018
488a33e
appveyor.yaml: try again to make system tests return error code 0
michaelDCurran Jun 7, 2018
f275871
appveyor.yaml: fix syntax of uplodFile.
michaelDCurran Jun 7, 2018
9b889f8
system tests: tell appVeyor they are junit formatted?
michaelDCurran Jun 7, 2018
c3b4a90
appVeyor: still upload test results on failed builds.
michaelDCurran Jun 8, 2018
8b0e1c2
Upload unitTest reports to appViewer as well.
michaelDCurran Jun 8, 2018
9270a20
Investigate freeze in robot test.
michaelDCurran Jun 8, 2018
30a1256
add some logging to nvdaRobotLib
michaelDCurran Jun 8, 2018
8e02fc4
More logging
michaelDCurran Jun 8, 2018
3824887
more logging again
michaelDCurran Jun 8, 2018
e244bcb
sleep before connecting to server.
michaelDCurran Jun 8, 2018
1c4f7b9
more and more logging
michaelDCurran Jun 8, 2018
d80c688
Fix logging...
michaelDCurran Jun 8, 2018
5e130c0
reimplement quit nvda test inside initial.robot.
michaelDCurran Jun 8, 2018
bdb51da
A try at moving everying to robot language to fix freezes.
michaelDCurran Jun 8, 2018
1286782
Launch NVDA from robot with py for appveyor.
michaelDCurran Jun 8, 2018
a57e95e
copy the globalPlugin.
michaelDCurran Jun 8, 2018
5d540e7
Temporarily start rdp for appveyor build
michaelDCurran Jun 8, 2018
8195ee4
bump
michaelDCurran Jun 8, 2018
6e530b6
bump 2
michaelDCurran Jun 8, 2018
38e696b
bump 3
michaelDCurran Jun 8, 2018
2274ea6
bump 4
michaelDCurran Jun 8, 2018
d8cd618
Slightly re-write now with setup and teardown, and insert q for quit …
michaelDCurran Jun 11, 2018
d6acae5
nvdaRobotLib: use a specific NVDA profile dir.
michaelDCurran Jun 12, 2018
5c55400
NVDA Spy for robot must use a daemon thread for now to stop further …
michaelDCurran Jun 12, 2018
06aa06b
Robot tests set NVDA not to show the welcome dialog
michaelDCurran Jun 12, 2018
ce75aa0
allow asserting on last speech
feerrenrut Jun 14, 2018
0c16f1b
Merge remote-tracking branch 'origin/robotOnAppveyor' into systemTest…
feerrenrut Jun 14, 2018
735991a
Remove extra tab characters
feerrenrut Jun 19, 2018
662eabb
Copy in the testSpy globalPlugin for each test.
feerrenrut Jun 20, 2018
08c8697
Remove sleep
feerrenrut Jun 20, 2018
8981697
Some cleanup of connection/disconnection code
feerrenrut Jun 20, 2018
669da0a
Extract code that can be reused and add better documentation
feerrenrut Jun 20, 2018
2bc3804
cleanup systemTest dir
feerrenrut Jun 20, 2018
6d2032a
Assert text on welcome dialog passes
feerrenrut Jun 20, 2018
b0477e8
Copy nvda log for each test
feerrenrut Jun 20, 2018
4f9149e
Try to get systemtest artefacts from appveyor
feerrenrut Jun 20, 2018
36e7ee8
Try manually pushing artifacts
feerrenrut Jun 20, 2018
e6a6fbf
Try recursing over files and pushing manually
feerrenrut Jun 20, 2018
4787753
Fix issue when nvdaProfile folders do not exist
feerrenrut Jun 20, 2018
e9f2189
system tests: don't show usage stats dialog in NVDA
michaelDCurran Jun 21, 2018
5321953
appveyor: install NVDA on the build system, and run the system tests …
michaelDCurran Jun 21, 2018
13b5397
appveyor: install nvda with start-process and wait up to 3 minutes fo…
michaelDCurran Jun 21, 2018
66b0005
fix appveyor errors
michaelDCurran Jun 21, 2018
6600242
Temprarily include robotremoteserver in NVDA for system tests. Must f…
michaelDCurran Jun 21, 2018
d02fe75
Breakup up appveyor test code into separate powershell code chunks to…
michaelDCurran Jun 21, 2018
c985677
system tests: use silence synth driver.
michaelDCurran Jun 26, 2018
a32f1aa
Merge master
michaelDCurran Jun 26, 2018
5c4d284
system test for exit dialog: just sleep instead of varifying dialog.
michaelDCurran Jun 26, 2018
844c73b
system tests: don't wait for exit dialog, rather just confirm that th…
michaelDCurran Jun 26, 2018
78432cf
appveyor: move NVDA installation to before_test section.
michaelDCurran Jun 26, 2018
221208e
ensure quit system test: exit from the NVDA menu.
michaelDCurran Jun 26, 2018
7bd259a
system tests: try alt tabbing to the exit dialog???
michaelDCurran Jun 26, 2018
6a757e1
More debugging for system tests.
michaelDCurran Jun 26, 2018
6edf1e0
IAccessibleHandler: more debugging.
michaelDCurran Jun 26, 2018
167b362
IAccessibleHandler: more debugging.
michaelDCurran Jun 26, 2018
27446cf
eventHandler: more debugging.
michaelDCurran Jun 26, 2018
ce6474a
Up max foreground defer count to 10.
michaelDCurran Jun 26, 2018
86aeb06
Up foreground defers to 100 and log them.
michaelDCurran Jun 26, 2018
8bfbf74
IAccessibleHandler: drop foreground defers back down and allow welco…
michaelDCurran Jun 26, 2018
8027682
system tests for quit with keyboard: watch for and close welcome dial…
michaelDCurran Jun 26, 2018
2913125
quit with keyboard system test: wait longer for NVDA to exit.
michaelDCurran Jun 26, 2018
e6e8188
Restore IAccessibleHandler and eventHandler.
michaelDCurran Jun 27, 2018
9fd13f4
Not able to get an index returned from get_index_of_speech
feerrenrut Jun 27, 2018
52853fc
tests passing
feerrenrut Jun 27, 2018
da0df66
move spy lib logic into spy
feerrenrut Jul 1, 2018
bc869e6
Install systemTestSpy as a package on setup
feerrenrut Jul 2, 2018
f20dc35
Cleanup files, add copyright headers
feerrenrut Jul 2, 2018
612659d
Use _ to prevent imports from leaking as keywords
feerrenrut Jul 2, 2018
5266301
Move non NVDA specific helpers into a new library
feerrenrut Jul 2, 2018
e3ae2a1
Merge remote-tracking branch 'origin/installed_systemTestWithRobot' i…
feerrenrut Jul 2, 2018
fd67383
Create self contained package for system test spy
feerrenrut Jul 3, 2018
f1be08f
Zip system test output before pushing to artifacts
feerrenrut Jul 3, 2018
da14b4b
try adding robotlibraries directory to the path
feerrenrut Jul 3, 2018
6818faa
Fix case of file name
feerrenrut Jul 3, 2018
39f6b07
further tidy up
feerrenrut Jul 4, 2018
50137bc
Introduce suite name
feerrenrut Jul 4, 2018
cbf6c7e
fix appveyor system tests
feerrenrut Jul 4, 2018
385e8ea
Stop double nvda install log artifact
feerrenrut Jul 4, 2018
df02377
set robot library path
feerrenrut Jul 4, 2018
44d94fd
reduce suite verbosity on appveyor
feerrenrut Jul 4, 2018
25f1897
Revert to running from repo root
feerrenrut Jul 5, 2018
9254b1e
Clean up some of the appveyor code
feerrenrut Jul 5, 2018
edb0e75
clean up some names and docs for tests
feerrenrut Jul 5, 2018
7bd629e
Add scons command to run system tests
feerrenrut Jul 5, 2018
2114664
ensure dir is created for std out/err logs
feerrenrut Jul 5, 2018
46cfaae
Merge remote-tracking branch 'origin/master' into systemTestWithRobot
feerrenrut Jul 6, 2018
f8606bc
Use dummy speech synth to get speech
feerrenrut Jul 6, 2018
c8b9199
wait longer before sending input
feerrenrut Jul 6, 2018
0e743ac
Stop update dialog from showing on startup
feerrenrut Jul 6, 2018
21eca3c
simplify the appveyor pip installs
feerrenrut Jul 6, 2018
be440a9
Update What's new
michaelDCurran Jul 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extras/controllerClient/x64
source/_buildVersion.py
user_docs/*/keyCommands.t2t
output
testOutput
source/brailleDisplayDrivers/handyTech
./developerGuide.html
user_docs/build.t2tConf
Expand Down
54 changes: 52 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ environment:

init:
- ps: |
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Having a comment here describing why this is downloaded might help potential future NV access devs if we lose access to the knowledge of why this was originally done.

if ($env:APPVEYOR_REPO_TAG_NAME -and $env:APPVEYOR_REPO_TAG_NAME.StartsWith("release-")) {
# Strip "release-" prefix.
$version = $env:APPVEYOR_REPO_TAG_NAME.Substring(8)
Expand Down Expand Up @@ -91,8 +92,8 @@ build_script:
Set-AppveyorBuildVariable "sconsArgs" $sconsArgs
- 'echo scons args: %sconsArgs%'
- py scons.py source %sconsArgs%
# We don't need launcher to run tests, so run the tests before launcher.
- py scons.py tests %sconsArgs%
# We don't need launcher to run checkPot, so run the checkPot before launcher.
- py scons.py checkPot %sconsArgs%
# The pot gets built by tests, but we don't actually need it as a build artifact.
- del output\*.pot
- 'echo scons output targets: %sconsOutTargets%'
Expand All @@ -113,6 +114,55 @@ build_script:
- 7z a -tzip -r ..\output\symbols.zip *.dl_ *.ex_ *.pd_
- cd ..

before_test:
- py -m pip install robotframework robotremoteserver pyautogui nose
- mkdir testOutput
- mkdir testOutput\unit
- mkdir testOutput\system
- ps: |
$errorCode=0
$nvdaLauncherFile=".\output\nvda"
if(!$env:release) {
$nvdaLauncherFile+="_snapshot"
}
$nvdaLauncherFile+="_${env:version}.exe"
Copy link
Collaborator

Choose a reason for hiding this comment

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

a couple of things.

  1. is this compatible with try builds?
  2. What if we offered a python function or something that gave us a launcher file name so we didn't have to do this, and later build the file name in appVeyor? we'd just call py versionBuilder.py, which would import things and use the environment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the tests run on try builds, against an install of NVDA. I can't speak to your second question, it might be best for @michaelDCurran to answer that one.

echo NVDALauncherFile: $NVDALauncherFile
$outputDir=$(resolve-path .\testOutput)
$installerLogFilePath="$outputDir\nvda_install.log"
$installerProcess=start-process -FilePath "$nvdaLauncherFile" -ArgumentList "--install-silent --debug-logging --log-file $installerLogFilePath" -passthru
try {
$installerProcess | wait-process -Timeout 180
$errorCode=$installerProcess.ExitCode
} catch {
echo NVDA installer process timed out
$errorCode=1
}
Push-AppveyorArtifact $installerLogFilePath
if($errorCode -ne 0) { $host.SetShouldExit($errorCode) }

test_script:
- ps: |
$errorCode=0
$outDir = (Resolve-Path .\testOutput\unit\)
$unitTestsXml = "$outDir\unitTests.xml"
py -m nose --with-xunit --xunit-file="$unitTestsXml" ./tests/unit
if($LastExitCode -ne 0) { $errorCode=$LastExitCode }
Push-AppveyorArtifact $unitTestsXml
$wc = New-Object 'System.Net.WebClient'
$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", $unitTestsXml)
if($errorCode -ne 0) { $host.SetShouldExit($errorCode) }
- ps: |
$testOutput = (Resolve-Path .\testOutput\)
$systemTestOutput = (Resolve-Path "$testOutput\system")
$testSource = "./tests/system"
py -m robot --loglevel DEBUG -d $systemTestOutput -x systemTests.xml -v whichNVDA:installed -P "$testSource/libraries" "$testSource"
Compress-Archive -Path "$systemTestOutput\*" -DestinationPath "$testOutput\systemTestResult.zip"
Push-AppveyorArtifact "$testOutput\systemTestResult.zip"
if($LastExitCode -ne 0) { $errorCode=$LastExitCode }
$wc = New-Object 'System.Net.WebClient'
$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path "$systemTestOutput\systemTests.xml"))
if($errorCode -ne 0) { $host.SetShouldExit($errorCode) }

artifacts:
- path: output\*
- path: output\*\*
Expand Down
13 changes: 13 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,16 @@ To run only the translatable string checks (which check that all translatable st
```
scons checkPot
```

You may also use scons to run the system tests, though this will still rely on having set up the dependencies (see `tests/system/readme.md`).

```
scons systemTests
```

To run only specific system tests, specify them using the `filter` variable on the command line.
This filter accepts wildcard characters.

```
scons systemTests filter="Read welcome dialog"
```
2 changes: 2 additions & 0 deletions sconstruct
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ vars.Add(ListVariable("nvdaHelperDebugFlags", "a list of debugging features you
vars.Add(EnumVariable('nvdaHelperLogLevel','The level of logging you wish to see, lower is more verbose','15',allowed_values=[str(x) for x in xrange(60)]))
if "tests" in COMMAND_LINE_TARGETS:
vars.Add("unitTests", "A list of unit tests to run", "")
if "systemTests" in COMMAND_LINE_TARGETS:
vars.Add("filter", "A filter for the name of the system test(s) to run. Wildcards accepted.", "")

#Base environment for this and sub sconscripts
env = Environment(variables=vars,HOST_ARCH='x86',tools=["textfile","gettextTool","t2t",keyCommandsDocTool,'doxygen','recursiveInstall'])
Expand Down
6 changes: 6 additions & 0 deletions source/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
from logHandler import log
import addonHandler

import extensionPoints

# inform those who want to know that NVDA has finished starting up.
postNvdaStartup = extensionPoints.Action()
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe that, according to earlier convention discussions we had, this should be post_NVDAStartup. Also note that it might make sense to write NVDA in upper case, as in NVDAObjects, NVDAHelper

Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be added to the changes file. This is useful for addons potentially.


PUMP_MAX_DELAY = 10

#: The thread identifier of the main thread.
Expand Down Expand Up @@ -470,6 +475,7 @@ def Notify(self):
log.debug("initializing updateCheck")
updateCheck.initialize()
log.info("NVDA initialized")
postNvdaStartup.notify()

log.debug("entering wx application main loop")
app.MainLoop()
Expand Down
2 changes: 2 additions & 0 deletions source/nvda.pyw
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ if globalVars.appArgs.debugLogging:
logLevel=log.DEBUG
logHandler.initialize()
logHandler.log.setLevel(logLevel)
if logLevel is log.DEBUG:
log.debug("Provided arguments: {}".format(sys.argv[1:]))

log.info("Starting NVDA")
log.debug("Debug level logging enabled")
Expand Down
2 changes: 1 addition & 1 deletion source/speech.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ def speak(speechSequence,symbolLevel=None):
import speechViewer
if speechViewer.isActive:
for item in speechSequence:
if isinstance(item,basestring):
if isinstance(item, basestring):
speechViewer.appendText(item)
global beenCanceled, curWordChars
curWordChars=[]
Expand Down
10 changes: 9 additions & 1 deletion tests/sconscript
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ unitTests = env.SConscript("unit/sconscript", exports=["env"])
env.Depends(unitTests, sourceDir)
env.AlwaysBuild(unitTests)

systemTests = env.SConscript("system/sconscript", exports=["env"])
env.Depends(systemTests, sourceDir)
env.AlwaysBuild(systemTests)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are these always built?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At the moment, the system tests only run if you explicitly give the option when starting scons. Then we want the tests to run, even if there has been no changes to dependencies.

env.Alias("systemTests", systemTests)

def checkPotAction(target, source, env):
return checkPot.checkPot(source[0].abspath)
checkPotTarget = env.Command("checkPot", pot, checkPotAction)
Expand All @@ -31,10 +36,13 @@ env.Alias("checkPot", checkPotTarget)
# If specific tests are explicitly specified, only run those.
explicitUnitTests = env.get("unitTests")
explicitCheckPot = "checkPot" in COMMAND_LINE_TARGETS
explicit = explicitUnitTests or explicitCheckPot
explicitSystemTests = "systemTests" in COMMAND_LINE_TARGETS
explicit = explicitUnitTests or explicitCheckPot or explicitSystemTests
tests = []
if not explicit or explicitUnitTests:
tests.append(unitTests)
if not explicit or explicitCheckPot:
tests.append(checkPotTarget)
if explicit and explicitSystemTests: # only run system tests explicitly
tests.append(systemTests)
env.Alias("tests", tests)
1 change: 1 addition & 0 deletions tests/system/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nvdaProfile/
57 changes: 57 additions & 0 deletions tests/system/NVDA Core/startupShutdownNVDA.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2018 NV Access Limited
# This file may be used under the terms of the GNU General Public License, version 2 or later.
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
*** Settings ***
Documentation Basic start and exit tests
Default Tags NVDA smoke test

Library OperatingSystem
Library Process
Library sendKey.py
Library nvdaRobotLib.py
Library helperLib.py

Test Setup start NVDA standard-dontShowWelcomeDialog.ini
Test Teardown quit NVDA

Variables variables.py

*** Test Cases ***
Starts
[Documentation] Ensure that NVDA can start
process should be running nvdaAlias

Quits from keyboard
[Documentation] Starts NVDA and ensures that it can be quit using the keyboard
[Setup] start NVDA standard-doShowWelcomeDialog.ini

${Welcome dialog title} = catenate double space Welcome to NVDA dialog
wait for specific speech ${Welcome dialog title}
wait for speech to finish
sleep 1 # the dialog is not always receiving the enter keypress, wait a little longer for it
send key enter

${Exit NVDA dialog} = catenate double space Exit NVDA dialog
send key insert q
${INDEX} = wait for specific speech ${Exit NVDA dialog}

wait for speech to finish
${actual speech} = get speech from index until now ${INDEX}
assert strings are equal ${actual speech} ${QUIT_DIALOG_TEXT}
sleep 1 # the dialog is not always receiving the enter keypress, wait a little longer for it
send key enter
wait for process nvdaAlias timeout=10 sec
process should be stopped nvdaAlias

Read welcome dialog
[Documentation] Ensure that the welcome dialog can be read in full
[Setup] start NVDA standard-doShowWelcomeDialog.ini

${Welcome dialog title} = catenate double space Welcome to NVDA dialog
${INDEX} = wait for specific speech ${Welcome dialog title}
wait for speech to finish
${actual speech} = get speech from index until now ${INDEX}
assert strings are equal ${actual speech} ${WELCOME_DIALOG_TEXT}
sleep 1 # the dialog is not always receiving the enter keypress, wait a little longer for it
send key enter
13 changes: 13 additions & 0 deletions tests/system/NVDA Core/variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
WELCOME_DIALOG_TEXT = (
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might break if a user runs the system tests with a system language other than English, in which the user default language differs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's likely that there will be lots of ways that the tests will not pass on various different systems. To start with, we will be using AppVeyor as the target. Over time, if people are trying to run the tests locally, then the tests will become more tolerant of variations in the underlying system.

"Welcome to NVDA dialog Welcome to NVDA! Most commands for controlling NVDA require you to hold "
"down the NVDA key while pressing other keys. By default, the numpad Insert and main Insert keys "
"may both be used as the NVDA key. You can also configure NVDA to use the Caps Lock as the NVDA "
"key. Press NVDA plus n at any time to activate the NVDA menu. From this menu, you can configure "
"NVDA, get help and access other NVDA functions.\n"
"Options grouping\n"
"Keyboard layout: combo box desktop collapsed Alt plus k"
)
QUIT_DIALOG_TEXT = (
"Exit NVDA dialog\n"
"What would you like to do? combo box Exit collapsed Alt plus d"
)
34 changes: 34 additions & 0 deletions tests/system/libraries/helperLib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2018 NV Access Limited
# This file may be used under the terms of the GNU General Public License, version 2 or later.
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html

"""This file provides general robot library functions for system tests.
This is in contrast with nvdaRobotLib.py which contains helpers related to starting and stopping NVDA for system
tests, or with systemTestSpy which contains methods for extracting information about NVDA's behaviour during system
tests.
"""
from robot.libraries.BuiltIn import BuiltIn
builtIn = BuiltIn() # type: BuiltIn

def assert_strings_are_equal( actual, expected, ignore_case=False):
try:
builtIn.should_be_equal_as_strings(
actual,
expected,
msg="Actual speech != Expected speech",
ignore_case=ignore_case
)
except AssertionError:
builtIn.log(
"repr of actual vs expected (ignore_case={}):\n{}\nvs\n{}".format(
ignore_case,
repr(actual),
repr(expected)
)
)
raise


def catenate_double_space(*args):
return " ".join(args)