This add-on gathers various features for NVDA debugging and testing.
This add-on uses layered commands for all of the new commands it adds.
The entry point for these commands is NVDA+X; thus all the commands should be executed by NVDA+X followed by another single letter or gesture.
You can list all the available layered commands pressing NVDA+X, H.
For the commands that you use more frequently, you can also define a direct gesture in the input gesture dialog.
The NVDA+X, Q command opens a dialog to specify some extra options before restarting NVDA.
The options that can be specified correspond to the command line options that can be used with nvda.exe, e.g. -c for config path, --disable-addons to disable add-ons, etc.
Pressing NVDA+X, E allows to report the last error logged without needing to open the log. A second press clears the memorized last error.
The "Play a sound for logged errors" setting has been introduced in NVDA 2021.3 and allows to specify if NVDA will play an error sound in case an error is logged.
This add-on provides an additional command (NVDA+X, shift+E) to toggle this setting.
You can choose:
For NVDA prior to 2021.3, this add-on provides the backport of this feature and the possibility to control it with the keyboard command. The checkbox in the Advanced settings panel is not backported however.
This feature allows to report some properties of the current navigator object without opening the log viewer.
To list the properties of an object, move the navigator object to it and use the following commands:
NVDA+X, upArrow: Selects the previous property and reports it for the navigator object.NVDA+X, downArrow: Selects the next property and reports it for the navigator object.NVDA+X, N: Reports the currently selected property for the navigator objectNVDA+X, shift+N: Displays the currently selected property for the navigator object in a browseable messageThe list of the supported properties is the following: name, role, state, value, windowClassName, windowControlID, windowHandle, location, Python class, Python class mro.
When using object navigation commands, you can also choose to have the currently selected property reported instead of NVDA usual object reporting.
A toggle command, NVDA+X, control+N, allows to switch between this custom reporting of objects and NVDA usual reporting.
For exemple, you may select "windowClassName" property and enable custom object reporting. Then when moving the navigator object to next or previous object, you will hear the object's windowClassName instead of usual reporting.
The add-on provides three commands allowing to open source code.
The first command allows to open the source code of a script knowing its gesture.
To use it press NVDA+x, C and then the gesture of the script which you want to see the code of.
For example to see the code of the script that reports the title of the foreground window, press NVDA+X, C and then NVDA+T.
The two other commands allow to open the source code from its path:
* NVDA+x, shift+C, opens the source code whose path is located under the system caret.
* NVDA+x, control+C, opens the source code whose path is located under the review cursor.
E.g. if the caret or the review cursor is located on the following line, the command will open the corresponding file in your editor:
C:\Users\username\AppData\Roaming\nvda\addons\addonName\globalPlugins\addonName\__init__.py:48
For those commands to work, you need to have configured your favorite editor's command in the add-on's settings. If you are not running NVDA from source, the location of NVDA source code should also have been configured.
The extended script description mode allows to have reported information on scripts without description in input help mode.
When the Extended script description mode is active, the input help mode (NVDA+1) is modified as follows.
If a script has no description, the script's name and class are reported.
If a script has a description, its description is reported as usual.
The gesture to activate or deactivate this feature is NVDA+X, D.
Executing a gesture bound to a script without description in input help mode also create an entry for this script in the gesture management dialog. This entry is located in a dedicated category called "Scripts without description (modify at your own risk!)". This allow to easily add, delete or change the native NVDA gestures for these script. Be aware however that it is often intended that such script do not have any description to prevent the user to modify the associated gesture. Indeed, the gesture may be defined to match an application shortcut key. For example the script script_toggleItalic on NVDAObjects.window.winword.WordDocument is bound to control+I and this should not be modified since the gesture is passed to the application to actually execute the shortcut key.
Control+shift+I also toggle italic in Word, even if it is not natively reported by NVDA. To have the control+shift+I result reported by NVDA as control+I, you should perform the following steps:
NVDA+X, D.NVDA+X, D.Known bug: A script added for a specific class is visible even if gesture manager is opened in another context.
While testing or working, you may want to mark a specific moment in the log, so that you can turn to it easily later when reading the log.
To add a marker message in the log, press NVDA+X, K.
A message as follows will be logged at INFO level:
-- NDTT marker 0 --
You can add as many markers as you want in the log.
The marker's number will be incremented each time you place a marker in the log; it will only be reset when NVDA is restarted.
A log reader mode provides commands to ease log reading and analyzing.
In the log viewer window and in the Pyton console output area, the log reader is enabled by default, thus log reading commands are available immediately.
In another text reading area such as an editor (e.g. Notepad++) or a webpage (e.g. GitHub issue), you need to press NVDA+X, L to enable log reader mode and use its commands.
When you are done with log reading and analyzing tasks, you can disable again NVDA+X, L to disable the log reader mode.
The commands available in log reader mode are described hereafter.
In this mode, you can also press control+H to display all the commands available.
Single letter command similar to browse mode quick navigation keys allow to move to various type of log messages:
ERROR and CRITICAL)WARNING)INFO)DEBUGWARNING)IO)DEBUG)Pressing the single letter moves to the next occurrence of this message. Combining the letter with the shift key moves to the previous occurrence of this message.
In addition, inside certain types of messages, you can jump block by block pressing O or shift+O.
The following message types and associated blocks are supported:
NVDA+F1, block navigation allows you to jump between groups of properties.
There are four groups of properties: general properties, appModule properties, window properties and interface-specific (IAccessible, UIA) properties.At last, inside a block, you may want to jump quickly to first or last line of interest of the block.
Use shift+L to jump to the first line of interest of the current block's content, e.g. the first frame of a traceback.
And L to jump to the last line of interest of the block's content, e.g. last frame of a thread stack or error below a traceback.
Sometimes, you may have to look at a log taken on a system in a foreignh language that you do not understand. E.g. the log was taken on a Chinese system / NVDA, whereas you only understand French. If you have Instant Translate add-on installed, you may use it in conjonction with quick log navigation commands to have speech messages translated.
control+T to enable automatic speech translation in the logIf you want to disable speech translation, press control+T again.
In the log some line may refer to the source code:
File "virtualBuffers\__init__.pyc", line 226, in _getStoryLengthINFO - config.ConfigManager._loadConfig (22:45:26.145) - MainThread (16580):Input help: gesture kb(desktop):NVDA+t, bound to script title on globalCommands.GlobalCommandsYou may want to open the file containing this code to understand the context of the traceback or the logged message. Just press C to open this file.
For this feature to work, you need to have configured your favorite editor's command in the add-on's settings. If you are not running NVDA from source, the location of NVDA source code should also have been configured.
Sometimes you may have error tracebacks in the log, as in the following example:
ERROR - scriptHandler.executeScript (14:47:43.426) - MainThread (15492):
error executing script: <bound method LogContainer.script_openSourceFile of <NVDAObjects.Dynamic_LogViewerLogContainerIAccessibleRichEdit50WindowNVDAObject object at 0x34C1E510>> with gesture 'c'
Traceback (most recent call last):
File "scriptHandler.pyc", line 300, in executeScript
File "C:\Users\myUserName\AppData\Roaming\nvda\addons\nvdaDevTestToolbox\globalPlugins\ndtt\logReader.py", line 603, in script_openSourceFile
if self.openStackTraceLine(line):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\myUserName\AppData\Roaming\nvda\addons\nvdaDevTestToolbox\globalPlugins\ndtt\logReader.py", line 667, in openStackTraceLine
0 / 0 # An erroneaous code line
~~^~~
ZeroDivisionError: division by zero
For frames where the source code is available, you may have noticed markers with ^ (caret) and ~ (tilde) characters.
That's the way Python visually indicates the error's location as well as its context in a traceback frame.
Pressing control+E moves the cursor at the beginning of the error in the source code line, i.e. the text marked by ^ (caret) character.
A double press, select this text.
A triple press selects the error with its context, i.e. the text of the source code line marked by ^ (caret) and ~ (tilde) characters.
Please note that for logs taken with an NVDA version before 2024.1, thus with Python 3.7 or older, Python only indicates the error with one ^ (caret) character.
Thus the double or triple press action of this command becomes rather useless.
To display a list of all the available commands in log reading mode, press control+H.
When reporting issues, you may have to provide a log. However, logs may contain sensitive information (user names, e-mails, etc.). This add-on provides a command to anonymize a log's content.
Select a part of the log or its whole content and press NVDA+X, A.
The anonymized log content will be put in the clipboard.
You can paste it on the current selection to replace it or anywhere else you wish.
For this feature to work, you need to customize the anonymization rules used by this command.
The file to configure these rules is located at: pathToNVDAConfig\ndtt\anonymizationRules.dic (e.g. C:\Users\myUserName\AppData\Roaming\nvda\ndtt\consoleStartup.py).
You will find all the instructions to write this file in its header.
In case you have corrupted your anonymization rules file or if you have deleted the header's instructions, just delete or rename this file and a new version of this file will be generated at next startup.
NVDA already provides a backup of the log of the previous session of NVDA; the file is called nvda-old.log.
Sometimes however you may want to access older logs, e.g. because you have had to restart NVDA again before looking at nvda-old.log.
This add-on allows you to configure if you want to backup old logs and how many of them; this is done in the add-on's settings.
A log manager dialog allows to view the backed up logs. It can be opened going to NVDA menu -> Tools -> Logs manager In this dialog, you can see the list of all the backup logs and perform various actions on the selected log:
Enter)Delete)control+C)You can also select multiple logs to perform an actions on all of them.
To be able to open a log, you should first have configured the Command to open a file in your favorite editor.
openCodeFile functionIn the console, you can call the following function to view the source code that defines the variable myVar:
openCodeFile(myVar)
For this feature to work, you need to have configured your favorite editor's command in the add-on's settings. If you are not running NVDA from source, the location of NVDA source code should also have been configured.
The openCodeFile functions can be called on objects defined in NVDA's code or on objects defined by add-ons.
It cannot be called on objects whose source code is not available such as python builtins.
If you have not yet imported the object in the console, you can also pass its name as parameter to the openCodeFile function.
Below are examples of call in NVDA's code:
speech.speech.speak:
openCodeFile(speech.speech.speak)
or with the name passed as parameter:
openCodeFile("speech.speech.speak")TextInfo:
openCodeFile(textInfos.TextInfo)copyToClipboard of the class TextInfo:
openCodeFile(textInfos.TextInfo.copyToClipboard)openCodeFile(focus)api.py defining the module api:
openCodeFile(api)You can define a custom script which will be executed in the Python console's namespace when it is first opened.
For example, the script allows you to execute new imports and define aliases that you will be able to use directly in the console, as shown below:
# Various import that I want in the console.
import globalVars as gv
import core
import ui
# Aliases
ocf = openCodeFile
The Python console script should be placed in the following location: pathToNVDAConfig\ndtt\consoleStartup.py
For example: C:\Users\myUserName\AppData\Roaming\nvda\ndtt\consoleStartup.py
Note: In Python 2, i.e. with NVDA 2019.2.1 or earlier, only pure ASCII scripts are supported; any other encoding such as Unicode is not supported.
In Python console history, you can use up and down arrows to review and modify previous inputs. Though, the list of previous inputs is cleared when exiting NVDA. This add-on provide an option, enabled by default, allowing to preserve Python console input history even when NVDA is restarted.
Sometimes, you may want to see which part of the code is responsible for speaking something.
For this, you can enable the function calls logging for the speech.speech.speak function pressing NVDA+X, S.
Each time NVDA speaks, a corresponding message will be logged, including the stack trace, allowing you to identify the code that has caused this speech output.
Once you are done, disable function calls logging with the same gesture.
The same way, you can choose to log the calls of output functions tones.beep, braille.BrailleBuffer.update or nvwave.playWaveFile to track the origin of a beep, braille output or a sound (e.g. spelling error sound).
The target function can be chosen in the add-on's parameters.
You can even log the calls stack of a custom function.
By default, the log of the function calls is performed using the "settrace" method: it uses sys.settrace, threading.settrace and/or threading.settrace_all_threads to install a tracing callback that is invoked on target function return event.
Alternatively, if you do not get satisfying results, you may opt for the "monkey patching" method where the target function (e.g. speech.speech.speak) is patched.
Both methods have limitations that may prevent function calls to be logged in specific combined conditions.
For example, the "settrace" method may not work with NVDA version lower than 2026.1, when the target function is run from a non-main thread and the function calls logging is enabled after the target function's thread has been started.
On the other hand, the "monkey patching" method may not work when the target function is imported through a from import statement (e.g. from tones import beep).
You can toggle the method used to log function calls in the dedicated setting or pressing NVDA+X, shift+S.
Many testers use NVDA in another language than English. But when reporting test results on GitHub, the description of the modified options or the messages reported by NVDA should be written in English. It's quite frustrating and time consuming to have to restart NVDA in English to check the exact wording of the options or messages.
To avoid this, the add-on provides two reverse translation commands allowing to reverse translate NVDA's interface such as messages, control labels in the GUI, etc.
NVDA+X, R uses NVDA's gettext translation to try to reverse translate the last speech.NVDA+X, shift+R uses gettext translations from NVDA and its add-ons to try to reverse translate the last speech.More specifically, the first string of the last speech sequence is reverse translated.
For example, in French NVDA, if I arrow down to the Tools menu named "Outils", NVDA will say "Outils sous-Menu o" which stands for "Tools subMenu o". If I press the reverse translation command just after that, NVDA will reverse translate "Outils" to "Tools".
Looking at the log afterwards, we can find the following lines:
IO - speech.speech.speak (23:38:24.450) - MainThread (2044):
Speaking ['Outils', 'sous-Menu', CharacterModeCommand(True), 'o', CharacterModeCommand(False), CancellableSpeech (still valid)]
This confirms that "Outils was the first string in the speech sequence.
In case the reverse translation leads to two or more possible results, a context menu is opened listing all the possibilities.
The result of the reverse translation is also copied to the clipboard if the corresponding option is enabled, which is the default value.
Reverse translation of NVDA strings is only available for NVDA version 2022.1 or above. For earlier versions of NVDA, only the add-ons strings are available for reverse translation.
Besides, in NVDA version 2019.2.1 or earlier, in case no reverse translation is found, a second attempt is made in the first part of the string.
Indeed, in these NVDA version, the speech sequence looks like this:
IO - speech.speak (12:39:12.684):
Speaking [u'Outils sous-Menu o']
We can see that an object label may be concatenated with role, state, shortcut, etc.
So if the reverse translation gives no result with the whole string, a second attempt is made on the part of the string before the double space (" ").
Though, this is not bullet-proof since we cannot exclude that a string actually natively contains a double space.
Some features of the add-on may require a specific configuration. A settings panel allows to enable them or to control how they work. To view and modify these settings, go to NVDA menu -> Preferences and select the category NVDA Dev & Test Toolbox. This settings dialog can also be accessed directly from the Logs Manager dialog.
These settings are global and can only be configured when the default profile is active.
Some features allow to see content in your favorite editor. This includes the commands to view the source file from a log, from an object in the console or from a typed gesture, as well as the log manager's Open button.
To use them, you first need to configure the command that will be called to open the file in your favorite editor.
The command should be of the form:
"C:\path\to\my\editor\editor.exe" "{path}":{line}
You should of course modify this line according to the real name and location of your editor and the syntax used by it to open files.
{path} will be replaced by the full path of the file to open and {line} by the line number where you want the cursor to be set.
For Notepad++ for example the command to type in the console would be:
"C:\Program Files\Notepad++\notepad++.exe" "{path}" -n{line}
When using a command to view the source file from a log, from an object in the console or from a typed gesture or a path, the file may belong to NVDA itself.
If you are not running NVDA from source, your NVDA only contains compiled files.
Thus you may specify here an alternate location where the corresponding source file will be found, e.g. the place where you have cloned NVDA source files, so that a source file can be opened anyway.
The path should be such as:
C:\pathExample\GIT\nvda\source
Of course, replace the path of NVDA source with the correct one.
Be sure however that the version of your source file (e.g. GIT commit) is the same as the one of the running instance of NVDA.
The combobox Backup of old logs allows to enable or disable the feature. If it is enabled, you can also specify below in "Limit the number of backups" the maximum number of backups you want to keep. These settings only take effect at next NVDA startup when the backup takes place.
This option allows to choose if the reverse translation command also copies its result to the clipboard.
If this checkbox is checked, Python console input history will be preserved when NVDA is restarted. If it is checked, you can also specify below the maximum number of inputs that will be saved. If it is unchecked, NVDA will behave as usual, i.e. the console history will be empty after restart.
This combobox defines the function whose calls will be logged when enabling function call logging. You can select the function among various output functions or opt for the custom function choice.
If you select the custom function choice, you will need to enter the complete name of the function you want log calls for.
This complete name should include its location (package, module, class, etc.).
Be careful to define the function with its original location, i.e. where it was actually defined, else, call logging is less likely to work.
For example, use speech.speech.getCurrentLanguage which targets the function defined in speech\speech.py, not speech.getCurrentLanguage witch target the symbol imported in speech\__init__.py.
This combobox defines the method used to identify function calls when function call logging is enabled.
This parameter can also be toggled pressing NVDA+X, shift+S.
When this method is modified, it will first apply the next time the function call log is activated; that is, it does not apply to current function call logging if currently enabled.
NVDA+X.
The existing commands have been modified accordingly.NVDA+X, R) to reverse translate the last spoken message.NVDA+X, C) to open the source code of the script associated to the next pressed gesture.enter to open the log, control+C to copy the log file and delete to delete a log file.openCodeFile function can now receive as parameter the object or a string containing its name.openCodeFile Python console's function and the command to open the source file corresponding to a line in the log.openCodeFile function is available to view the source code of an object.