ElementaryBlock Element/en
Inhaltsverzeichnis
Introduction[Bearbeiten]
An elementary block provides the basic functionality of an expecco testsuite. It is used to model basic calculations or logical combinations, or to query and control external devices. These can be local or remote processes as well as hardware devices that are attached by some kind of hardware interface.
The behavior of an elementary block is defined by one of the following:
- a piece of textual program code, which is written in a particular programming language, which executes inside expecco
- a piece of code, written in Groovy, which executes on the system under test
- a call to a DLL (shared library) function
- a call to an external program (script)
- a remote procedure call
Expecco provides built in language interpreters and compilers for two scripting languages: the built In Smalltalk and the built in JavaScript-like scripting language. When such an elementary block is executed, the script code runs inside the expecco process. These support high level symbolic debugging including single-step, breakpoints or inspection of variables. The debugger even allows for code changes to be done to the running program (for example, if the program is stopped at a breakpoint).
Additional built In scripting languages (Ruby and Lisp) are being prepared.
Other scripting languages (Perl, TCL, Python, etc.) can be called via external script interpreters. It is also possible to call existing command line scripts (Shell under Unix or Windows+cygwin, Batch under Windows).
Finally, with the Java Bridge extension plugin, elementary blocks can also be written in Groovy, which is a scripting language with a syntax similar to Java, and which is transparently (and dynamically) compiled to Java bytecode, to be executed inside the system under test. Groovy blocks are useful to define callbacks, subclasses of existing classes or to set up complicated Java objects inside the tested Java application. When such a block is executed, the script code runs inside a JavaVM, which can be either a local one, dedicated to script execution, or on the target system (the system under test). More detail is found in the Expecco API Documentation.
The source code is usually edited in the code editor. It is interpreted according to the used language’s syntax at runtime. For the builtin languages Smalltalk and JavaScript, it is possible to switch the syntax pattern for already implemented blocks, causing the code to be automatically converted to that particular syntax style. The values of data pins can be directly accessed (read and write) in the code using the pin's name. The external interface of an elementary block (e.g. number of pins) is defined in the schema editor.
Notice that the standard library as delivered already contains a number of useful elementary blocks for a wide range of applications. So that the need to define your own elementary blocks is often limited to special interfacing or specialized processing of data.
Smalltalk and JavaScript Block Examples[Bearbeiten]
Here is a block to compute the minimum and maximum values of a mathematical function over a range of x-values. It is especially flexible, as the name of the function can be passed as an argument (for example: 'sin', 'cos' or 'arcTan'). The block's definition is:
and its code could be written in Smalltalk as:
execute
|fn minY maxY y|
fn := functionName value asSymbol.
(x0 value) to:(x1 value) by:(dX value) do:[:x |
y := x perform:fn.
minY := minY isNil ifTrue:[y] ifFalse:[ minY min:y ].
maxY := maxY isNil ifTrue:[y] ifFalse:[ maxY max:y ].
].
min value:minY.
max value:maxY.
or in JavaScript as:
execute() {
var fn, minY, maxY, x, y;
fn = functionName.value().asSymbol();
for (x = x0.value(); x <= x1.value(); x += dX.value()) {
y = x.perform(fn);
minY = (minY.isNil()) ? y : minY.min(y);
maxY = (maxY.isNil()) ? y : maxY.max(y);
}
min.value(minY);
max.value(maxY);
}
(notice the use of the "perform"-function, to call a function by name)
Of course, as usual, there are multiple ways to write the same function; an experienced Smalltalker would write:
execute
|fn minMax|
fn := functionName value asSymbol.
minMax := ((x0 value) to:(x1 value) by:(dX value))
collect:[:x | x perform:fn])
minMax.
min value:minMax first.
max value:minMax second.
and a JavaScript programmer might prefer:
execute() {
var fn, minY, maxY, x, y;
fn = functionName.value;
for (x = x0.value; x <= x1.value; x += dX.value) {
y = x.perform(fn.asSymbol());
minY = (minY == null) ? y : Math.min(minY,y);
maxY = (maxY == null) ? y : Math.max(maxY,y);
}
min.value(minY);
max.value(maxY);
}
The block could be used to calculate the min/max of the sine function in the range 0..1 as follows:
Shell Script Blocks[Bearbeiten]
Under the Unix operating system (incl. linux, solaris) or Windows plus Cygwin (or a similar shell implementation which is bash/ksh compatible), you can also execute shell-script blocks. For example, here is a script to read its input, filter all lines beginning with some pattern, sort them, and pass them on as output:
grep "^xx" | sort
of course, arbitrarily commands can be called (even programs with their own GUI). Under Windows, make sure that you have installed an appropriate shell emulator, and that it is either found along the PATH, or that you have specified the sh-path in the expecco-settings dialog (in "External Tools" - "Shell Path").
Batch Script Blocks[Bearbeiten]
These are similar to shell scripts, but use the Windows-batch file syntax. These cannot be executed on Unix systems, so your tests become OS-dependent, if you use them. The example code below would check out some source code from a cvs repository and start a build:
REM
REM batch file script (windows only)
REM
echo Checking out...
cvs co myProgram
cd myProgram
echo Building...
make
DLL-Calls[Bearbeiten]
DLL-call blocks define an interface to a function which is contained inside a DLL (Dynamic Link Library). For a dll-call to be possible, the functions attributes have to be entered into the dll-call editor. These are:
- name of the dll (for example: "user32.dll")
- name of the function within the dll
- the calltype (WINAPI or C-Call).
- the number and types of the arguments
- the type of the return value.
In addition, it is possible to specifiy that the dll-call is to be executed by a separate API-call thread. This avoids a blocking of the expecco user interface and other executing activities, for long running dll-calls. (asynchronous dll-calls are only supported by expecco rel. 1.7.4 and later)
SOAP-Calls[Bearbeiten]
These blocks define a remote procedure call via the SOAP protocol. SOAP blocks are normally generated automatically, by importing a wsdl service description. For more information, please refer to the WSDL Import Plugin description.
XML-RPC-Calls[Bearbeiten]
These blocks define XML-RPC remote procedure calls. XML-RPC is a very light-weight and low-overhead XML-based protocol, which is supported by many service oriented applications (among them, expecco and expeccoNET themself). For an XML-RPC call, the following information is mandatory:
- URL of the service (for example: "http://myhost:8080/rpc/xmlrpc")
- Name of the function (method)
There are 3 alternative ways, to specify the URL:
- hardwired as a string in the blocks specification (not recommended)
- via an environment variable
- via a pin value (freeze or dynamic)
Hardwired Service URL[Bearbeiten]
Because this is very unflexible, it should be only used for very constant URLs, or while exploring a service interface. For this, type the URL into the blocks specification form.
Specifying the Service URL via an Environment Variable[Bearbeiten]
Use a macro-replacement pattern such as "%(RPC_HOST)" in the URL field (as above). This will be replaced by a corresponding variable name from the reachable environment variable named accordingly. You can either specify a full URL (i.e. host, port and path) or a partial URL using this mechanism. For example, you can also provide the URL via 3 separate environment variables, by entering: "%(RPC_HOST):%(RPC_PORT)/%(RPC_PATH)". A runtime error will be reported, if the variable expansion leads to an invalid URL. However, if a missing expansion leads to a valid URL, no error is reported. This allows for optional fields to be added to the URL, for example as in: "%(JIRA_HOST)%(OPTIONAL_RPC_PORT)/jira/rpc/xmlrpc".
Providing the URL via an Input Pin[Bearbeiten]
Add an input pin with the (obligatory) name "url", and deliver it a string value. This is the most flexible way, as the URL value can be dynamically generated by any other block, or be provided via a pin-freeze value. If a url-pin is present, but not connected, it is ignored and the above variable mechanism is used. Otherwise, the pin-value takes precedence over any value in the specification.
See Also[Bearbeiten]
For a list of already existing blocks, see Standard Library
For the programmer API for the built in languages see: Expecco API
For information on the functions avaliable in the built-in classes, please refer to the [Smalltalk/X Online Documentation] and especially the [Class Reference].
For example, some of the mathematical functions are described [here]
and String processing functions are found
[here] and
[here].
Introduction[Bearbeiten]
All elements of a testsuite are organized as a hierarchical tree and are referred to as "Tree Elements" of a test suite. They are displayed and managed in the so-called project- or navigation tree, which is shown on the left of the expecco application. The test suite being edited is shown as the top-element in the tree.
For historical reasons, the Test Suite is also sometimes referred to as "Test Project" or just "Project" in this document.
The organization of the elements (i.e. the parent-child relation) has no semantic meaning. You can arrange them as you like, without affecting the execution. This may be different from other tools, and is especially relevant for test plan items: in expecco, the test cases are defined in the test plan's list and dragged from the tree into the list (In many other tools, test cases of a test plan are defined as child elements in the tree).
The advantage of this scheme is that test cases and actions can be reused in multiple test plans.
Common Attributes of all Tree Items[Bearbeiten]
Name[Bearbeiten]
You can give tree items an arbitrary name. This name is not used within expecco to reference an item (see "IDs"-Section below). Thus, you can change the name of any item at any time without a need to search for uses of the item (1). Because all references are via the ID, this also applies to any suite which imports your suite, or suites which you have imported. The references will be correct, and new names will appear automatically.
The name can be further translated by a model language translation table, so that both the user interface of expecco and the names attached to items are translated by different translation mapping tables. This makes it possible to present the same model to team users speaking different languages. Notice that the "UI-language" (which is used for Menus, Labels, Buttons etc.) can be different from the "Model Language", which is used to label elements in the tree and diagrams. Both settings are changed via the "Extras" - "Language Settings" dialog and are stored in your personal settings file. The UI translations are provided by expecco (and found in resource files, which are part of the installation), whereas the model translations are stored in the suite.
IDs[Bearbeiten]
Each element in the project has two special IDs (Identifiers). One is the so called "Functional-ID" which is assigned once, when the element is created initially and never changed thereafter. The other is the "Version-ID". This is reassigned with every modification. Inside expecco, elements are referred to by their ID, not by name. This makes it easy to change the name at any time later without a need to change other parts of the suite.
The "Version-ID" is used to quickly detect identical elements (for example, when merging projects from different files).
The "Functional-ID" is used when reimporting libraries; i.e. to identify which blocks should be automatically replaced by newer versions.
The name of a tree element is not used by the system to identity elements. Instead, it is only used for presentation to the user. By using IDs, reimport, compare and merging of libraries is possible without conflicts or indeterminism, even if elements have been renamed in the meantime. IDs are worldwide unique. This means, that no two items have the same ID unless they are identical items Technically, these IDs are UUIDs as described in RFC4122.
WARNING[Bearbeiten]
As described above, the ID of a suite plays a major role in expecco's reimport mechanism (i.e. when you upgrade an imported library to a newer version). Expecco checks if the function-ID of the library-to-be-imported matches the function-ID of the already imported library, and if they match, then reimports all individual action blocks again by using the function-IDs as reimport criteria.
This can be done automatically, and expecco can search for new versions of a given library within a folder, and perform such update-reimports for you. Whenever a suite is saved, the functionID of the suite remains unchanged, and expecco assumes, that you are simply writing a new version of that suite to a file.
However:
If you ever save a suite/library under a different name, and use this as the starting-base for a new suite/library, you should also assign a new versionID to that suite before saving. This tells expecco, that your intent is to make this a new suite, which is not to be considered in future reimport operations. On the other hand, if you change the function-ID of a library, it will no longer be considered to be a different version of the library and will refuse the reimport.
The same applies to the IDs of individual actions.
Tags[Bearbeiten]
Symbolic tags can be attached to tree elements. The main use of a tag is to group items by function and make finding items in search boxes easier. The search function provides a check box to enable/disable searching by tag.
Some wellknown tags affect the behaviour of the editor:
- elements tagged as "obsolete" will not be presented in dialogs to insert or drag&drop new steps.
- elements tagged as "private" will only be presented inside their library/project, but not outside.
In addition, tags can be used to filter tests for execution or to associate colors or icons. For example, the diagram settings dialog allows for particular colors and icons to be attached to particular tags. You can use this to mark critical, obsolete, input/output related or other items by color both in the tree and in activity diagrams.
Finally, tags are used to identify GUI actions, and only actions with matching tags are presented in the GUI browser's action/attribute selection trees. If you add corresponding tags to your own actions, the GUI browser will present them in addition to the gui library actions.
Tagged Values[Bearbeiten]
Some tree elements also allow for additional tagged values to be attached to it. Tagged values are tuples consisting of "name", "type", "value" and additional "attributes". For example:
("Foo", Integer, 123, READONLY)
Tagged values are not (currently) used by expecco itself. They may be needed when models are imported or exported from/to other modelling tools, such as Enterprise Architect, Rose etc. These programs use tagged values to specify stereotypes, connections and other attributes of a model element. When tagged values are attached to an element, these are handled transparently by expecco - i.e. they are not touched and left for other tools to be used. When loading a suite, they are remembered and saved unchanged when the suite is later saved back onto a file.
Test Items[Bearbeiten]
Testplan[Bearbeiten]
A testplan contains a list of "test cases", also called "test case items" or "test items" for short. A test case item can be either an action (i.e. a block), or another testplan. Test cases within a test plan are normally executed sequentially, until either the last test case has been executed, or any test case reports a failure or error. However, individual items can be skipped or marked as optional, which means that their outcome does not stop the overall testplan execution.
Please navigate to "Testplan" for more detais.
Performancetest[Bearbeiten]
A performance test consists of three types of items:
- load generators
- measuring blocks
- test actions
Together, these generate load on the system under test and measure its behavior during the test action execution.
Support for performance tests is being developed and an as-yet unpublished feature of expecco.
Libraries[Bearbeiten]
Libraries are collections of tree items to be reused (i.e. imported) in other suites or libraries. Libraries can contain any type of element, including test plans, datatypes, attachments, elementary and compound blocks. Libraries can also use and import additional libraries. There is no technical difference between a library and a suite. Any suite can be saved as ".ets" file, and imported by any other suite. When imported, they are found under the "Imports" node in the navigation tree.
Libraries like the Standard Library or the Qt-Interface Library and others are provided by eXept either as part of the standard delivery, or as additional extension, which must be purchased (licensed) separately. However, you can (and usually will) also create your own project-specific libraries. Or provide them as a supplier to a third party, or acquire them from a third party.
Already included in all releases of expecco are a number of libraries; among them are:
- Standard Library, which contains actions of general use
- Selenium Library, which interacts with web browsers
- ODBC Library, to access databases
- XML Library, to parse and manipulate XML documents
- Reflection Library: to manipulate expecco projects and to automate expecco itself
- Manual Test Library, to implement semi-automatic (user interacting) tests
Upon request, other libraries are available. For example:
- Interfaces to specific rich-client GUIs (Qt, Java SWT, Java Swing, Java FX, Android, Windows Mobile, iOS, ST/X, Ranorex)
- Interfaces to specific applications like SAP, Siebel,...
- Interfaces to other QM systems, like Polarion, HP-Quality Center
- Interfaces to bug tracking systems like JIRA
- Other Databases like Cassandra, Sqlite and others.
- Importers/Generators for Webservices, WSDL/SOAP, WADL/REST and XML-RPC
- CAN/MOST
- MQTT, Some/IP, ZeroMQ
- GPIB, VISA, OPC-UA
- Importers for test-description/activity diagrams in various formats (Excel, Word, Enterprise Architect, MindMap)
- Various Document and EDI formats (EDIFACT, IDoc, PDF, XML, IDL, etc)
Importing a library[Bearbeiten]
To import a library, either select the "File" → "Import Library" item from the main menu, or the "Import Library" from the "Imports" tree item's pop up menu:
A dialog will appear in which you should navigate to the folder containing the library, then select the library to import. Notice that the dialog will show the previously used folder initially.
For quick navigation to the expecco libraries folder, press the -button.
This button also provides a pull-down list of other useful folders, especially the folders of additional licensed plugins. The delayed menu of the back-button (keep the mouse button pressed a little longer) lets you navigate to a previously visited folder. The bookmarked folder button (the one with the red heart) lets you add manage your own preference list of folders for quick navigation.
After the import, the library's items are shown under the "Imports" folder, and items from it can be dragged into your diagram.
Reimporting a Library[Bearbeiten]
By default, imported libraries behave like "statically linked code". This means, that a copy of the required parts of the imported library is loaded into the test suite. After the import, the suite is independent of the original imported library: it can be changed, enhanced or even deleted (which you should not) without affecting the testsuite which imported it. This "static linkage" has two consequences:
- on the "plus" side, this prevents the "DLL hell", commonly known in the MS Windows world, where the installation of new libraries may affect functions in other parts of the system which happen to import that library. On Windows, programs which were known to work perfectly may become faulty, after an update or an installation of a new library version. This silently affects programs which have not been touched or modified.
With "static linkage", this can never happen. If a suite worked at some time in the past, it will continue to do so, even if other group members change or break the import library.
It is also often required for legal (i.e. proof) reasons: you can at any later time be sure which code/action was executed, and that very version of your suite can be re-executed with the same behavior, unaffected by any change done to a used library function.
- on the minus side, this means that in order to update to new version of a library, an explicit action has to be made. Thus, you have to actively "enforce" a "reimport operation" and update if you wish so. With deeply nested import libraries, this may become a tedious task, as you have to first reimport any sub-imports, save the library and then reimport that one. For this, additional tools and menu functions are provided, to perform recursive reimports. These effectively automate such tasks (although the tool may ask for user interaction, in case of conflicts).
Notice, that a reimport is a non-trivial operation: there might be new pins, changed datatype definitions, missing actions which were present before and many other possible problems. The reimport operation will detect these and provide appropriate trouble-resolving dialogs. Also, it is completely protected by the undo mechanism: if there is too much trouble with the new version, you can go back to the original and import individual blocks manually via drag & drop, replace blocks and rewire missing connections as required.
If a block was previously imported, but is no longer present in the new library version, a folder named "Lost & Found" is created, and the previously imported block can be found there.
Virtual Library[Bearbeiten]
Virtual libraries allow for the behavior of a group of actions to be specified and changed at runtime. Similar to abstract functions in an OO-programming language, virtual blocks only define the interface (number and types of pins) of a block, but no concrete implementation. A virtual library is a collection of such virtual blocks. Its components can be used and placed like any other block within a test scenario.
However, for execution, a concrete library needs to specified, which contains concrete implementations for every virtual block. The choice of a concrete library can be done statically or even dynamically at execution time (for example, to dynamically determine which communication protocol is required, and associate corresponding implementation blocks at the time the system under test is investigated).
Action Blocks[Bearbeiten]
Elementary Block[Bearbeiten]
Elementary blocks describe actions which are implemented as low-level primitives. These are either implemented in a builtin programming language (such as JavaScript, Smalltalk), a language running in the System Under Test or on a third machine (Groovy for Java, C# and Python for DotNET, C/C++, Node or Python), or an external script interpreter (for example, Shell, Batch, Perl, Python, Ruby or Go) or by calling an existing function written in any language either in a DLL (shared library) or via a remote procedure call (SOAP, XML-RPC, REST etc.).
Elementary blocks are usually provided by programmers or by eXept, as part of their standard or plugin libraries. They are typically used to implement low-level functionality, helper blocks or communication interfaces which are required by higher level test scenarios or to perform cpu intensive tasks (math, FFT, bulk data analysis).
Most of the elementary blocks code consists of onle a few lines of code. The code of elementary blocks is stored within a suite and can be inspected (and even changed) at any time - even during a test suite's execution. There is no need to recompile, link or even shut down the expecco system, when an elementary block's code is changed (the change will be in effect when the action is invoked the next time).
Please navigate to "Elementary Block" for more detail on elementary blocks.
Compound Block[Bearbeiten]
A compound block is a block which is defined by an internal activity diagram. This diagram contains blocks which themself are either elementary or compound. This makes every block highly reusable, as arbitrary complex hierarchies of actions are possible. Semantically, these diagrams are similar to petri nets or UML activity diagrams: the flow of information between blocks is via data flow: outgoing values are forwarded to other blocks via connections. Blocks are activated and executed, whenever its required inputs are arriving. Like elementary blocks, their definition can also be changed at any time - even during the execution of a suite (you may want to pause the execution, though).
Please navigate to " Compound Block" for more detail.
Keyword Action Blocks[Bearbeiten]
Simple sequential actions can also be defined in a tabular keyword-action representation. This presents actions to be performed as a table with input/output values. Of course, sequential execution is a subset of the more general execution structure in a compound action, in that they define a strictly sequential list of actions to be executed. And can as such be represented in a compound network as well. Although they cannot represent parallel execution, branches and loops, many beginners prefer the simpler user interface provided by keyword actions.
If there is a need for more complex control structures, keyword actions can be later converted to full-featured compound blocks, if there is a need.
Please navigate to " Keyword Action Blocks" for more detail.
Virtual Block[Bearbeiten]
A virtual block is used to place a step whose execution is defined dynamically at runtime. Similar to a virtual function in programming languages, only the block's interface is defined in a network. At execution time, one of multiple concrete actions is chosen to be actually executed. Virtual blocks are very useful, if the same sequence is to be executed on multiple different technologies or devices. For example, if different measurement devices, different protocols or different mobile devices are to be used in a test, and the type is to be determined dynamically when the test is started or even during the test run. Using virtual block libraries, it is possible to replace a whole bunch of actions with alternative implementations, without a need to change anything in the diagrams.
The determination of which concrete block to use can be done via two mechanisms:
- by importing a concrete library for a virtual library
- by specifying explicitly which concrete action to use
With the first strategy, you have to import a concrete library, which contains concrete implementations for all virtual blocks in the virtual library.
With the second strategy, you add a "Performer-Pin" to the virtual step, and pass the concrete block as argument. This can be either a freeze value, or a performer-reference-value computed or passed in from another block. It may also be a performer-reference value from an environment variable.
Please navigate to "Virtual Block" for more detail.
Test Data Generator Block[Bearbeiten]
A test data generator block is used to generate simple tabular data for a test. You specify rows for data tuples (similar to database rows of data columns), and time-deltas. When executed, the data generator will generate value tuples at its output pin(s) which should be fed as input to other blocks.
Please navigate to "Test Data Generator Block" for more detail.
GUIBlock Element[Bearbeiten]
A compound GUI block is used to model non-modal user interfaces. The action blocks contain a UI and a compound network, to implement more complex, stateful user interfaces. Their use is described in a separate document.
Please navigate to "GUIBlock Element" for more detail.
Elementary GUI Block[Bearbeiten]
This is an action block which opens a GUI in a modal dialog when executed. The GUI can be edited to contain arbitrary components (check boxes, input fields, buttons etc.). When closed, the entered values are send to the UI-block's output pins.
Such elementary GUI blocks are perfect to let the tester enter complex data during execution time. Notice, that for simple values (strings, numbers, filenames, yes-no questions, etc.), the standard library already contains a number of existing blocks (in the Dialogs folders).
Management[Bearbeiten]
Datatype[Bearbeiten]
A datatype element represents a user-defined data types. There are both builtin types (String, Integer, etc.) and user defined types, which can be constructed by various mechanisms (structures, unions, classes, enums, tuples, arrays, etc.)
Please navigate to "Datatype" for more detail.
Resource[Bearbeiten]
A resource element represents a physical, logical or human resource. Examples for physical resources are measurement devices, machine equipment or human operators. Non-physical resources are database-locks or synchronization semaphores. Expecco includes a resource management, which can be used to synchronize concurrent access and use of such resources within a test suite. If running under the control of the expeccoNET QM system, resources are even managed and access is controlled among multiple testhosts, while executing multiple tests in parallel.
Please navigate to "Resource" for more detail.
The relation between Skill, Resource and Inventory is demonstrated in an example in the Skill documentation.
Skill[Bearbeiten]
A skill is a part of the description of a resource or the requirement of a block. It describes a particular attribute of a resource.
Please navigate to "Skil" for more detail.
The relation between Skill, Resource and Inventory is demonstrated in an example in the Skill documentation.
Inventory[Bearbeiten]
An inventory is a collection of resources.
Please navigate to "Inventory" for more detail.
The relation between Skill, Resource and Inventory is demonstrated in an example in the Skill documentation.
Miscellaneous[Bearbeiten]
Folder[Bearbeiten]
Folder elements are containers for grouping of other elements.
Please navigate to " Folder" for more detail.
Attachment[Bearbeiten]
An attachment is used to manage any file together with a test suite.
Please navigate to "Attachment" for more detail.
Documentation[Bearbeiten]
Documentation elements can be used to add additional documentation to the test suite. They are simple text-holding elements, and typically contain instructions from the test developer to the test operator.
Please navigate to "Documentation" for more detail.
Report Template[Bearbeiten]
A report template is used to customize a report. It is a kind of "attachment" describing the format, layout and detail of a report. Multiple report templates can be embedded inside a suite (or a template library) and used to manually or automatically generate multiple different reports from the same run. (manually via the menu; automatically via report-generator action blocks).
Please navigate to "Report Template" for more detail.
See Also[Bearbeiten]
- Navigation Tree - user interface and functions provided by the navigation tree
- Editors - editor functions depending on the selected tree item