chr
2026-04-05 fe750b791d5b517cc4e9bc8e99a9a75139a0cfba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//            Copyright Keysight Technologies 2012-2019
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at http://mozilla.org/MPL/2.0/.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml.Serialization;
 
namespace OpenTap
{
    public class StepResult
    {
        public bool PassFail;
        public string StringValue;
    }
 
    /// <summary>
    /// <see cref="TestPlan"/> or <see cref="TestStep"/>. Specifies that a class can be inserted into the test plan hierarchy.
    /// </summary>
    public interface ITestStepParent
    {
        /// <summary>
        /// Parent TestStep for this TestStep. Null if this TestStep is not a child of any other TestSteps. 
        /// Only guaranteed to be set during <see cref="TestPlan.Execute()"/>. 
        /// </summary>
        [XmlIgnore]
        ITestStepParent Parent { get; set; }
 
        /// <summary>
        /// Gets a list of child TestSteps.
        /// </summary>
        [Browsable(false)]
        TestStepList ChildTestSteps { get; }
 
        void InsertStep(string name, int index, ITestStep testStep);
        void AddStep(string name, ITestStep testStep);
    }
 
    /// <summary>
    /// An interface for a <see cref="TestStep"/>. All TestSteps are instances of the ITestStep interface.
    /// 
    /// <para>---------------------------------------------------------------------------------------------------</para>
    /// 
    /// <para>The following attributes are mandatory</para>
    /// <para><seealso cref="ITestStepParent.Parent"/> [XmlIgnore]</para>
    /// 
    /// <para>---------------------------------------------------------------------------------------------------</para>
    /// 
    /// <para>The following attributes are recommended:</para>
    /// <para><seealso cref="ITestStepParent.ChildTestSteps"/> [XmlIgnore]</para>
    /// <para><seealso cref="Enabled"/> [Browsable(false)] [ColumnDisplayName("", Order = -101)]</para>
    /// <para><seealso cref="Id"/> [XmlAttribute("Id")] [Browsable(false)]</para>
    /// <para><seealso cref="PlanRun"/> [Browsable(false)]</para>
    /// <para><seealso cref="StepRun"/> [Browsable(false)]</para>
    /// <para><seealso cref="IsReadOnly"/> [XmlIgnore] attribute.</para>
    /// <para><seealso cref="TypeName"/> [ColumnDisplayName("Step Type", Order = 1)] [Browsable(false)]</para>
    /// <para><seealso cref="Verdict"/> [Browsable(false)] [ColumnDisplayName(Order = -99)] [XmlIgnore] [Output]</para>
    /// </summary>
    [Display("Test Step")]
    public interface ITestStep : ITestStepParent, IValidatingObject, ITapPlugin
    {
        // TODO (breaking): Split ITestStep so the base implementation does not have PrePlanRun and PostPlanRun.
        //                  That way we can quickly see if someone implements those methods without having to do it with reflection.
 
        /// <summary>
        /// Gets or sets the verdict. Only available during <see cref="TestStep"/> run. 
        /// This property value is propagated to the <see cref="TestStepRun"/> when the step run completes.  
        /// </summary>
        [Browsable(false)]
        [ColumnDisplayName(Order: -99, IsReadOnly: true)]
        [XmlIgnore]
        [Output]
        Verdict Verdict { get; set; }
 
        /// <summary>
        /// ¸ùPlan,Çø±ðÓÚÔËÐÐʱGetParent(TestPlan)
        /// </summary>
        public TestPlan Root { get; set; }
 
        /// <summary>
        /// Name of the step. Should be set by the user if using multiple instances of the same type.
        /// </summary>
        [ColumnDisplayName(nameof(Name), Order: -100)]
        [Browsable(false)]
        string Name { get; set; }
 
        /// <summary>
        /// Gets or sets boolean value that indicates whether this step is enabled in the <see cref="TestPlan"/>.  
        /// </summary>
        [Browsable(false)]
        [ColumnDisplayName("", Order: -101)]
        bool Enabled { get; set; }
 
        /// <summary>
        /// Gets or sets the current <see cref="TestPlanRun"/>.  
        /// </summary>
        [Browsable(false)]
        TestPlanRun PlanRun { get; set; }
 
        /// <summary>
        /// Gets or sets the currently running and most recently started <see cref="TestStepRun"/>.
        /// </summary>
        [Browsable(false)]
        TestStepRun StepRun { get; set; }
 
        /// <summary>
        /// Gets or sets boolean value that indicates whether this step is read only in the <see cref="TestPlan"/>.  
        /// </summary>
        [Browsable(false)]
        [XmlIgnore]
        bool IsReadOnly { get; set; }
 
        /// <summary>
        /// Name of this <see cref="TestStep"/> type.  
        /// </summary>
        [ColumnDisplayName("Type", Order: 1)]
        [Browsable(false)]
        string TypeName { get; }
 
        StepResult Result { get; set; }
 
        /// <summary>
        /// Called by TestPlan.Run() for each step in the test plan prior to calling the TestStepBase.Run() methods of each step.
        /// </summary>
        void PrePlanRun();
 
        /// <summary>
        /// Called by TestPlan.Run() to run each TestStep. 
        /// If this step has children (ChildTestSteps.Count > 0), then these are executed instead.
        /// </summary>
        void Run();
 
        /// <summary>
        /// Called by TestPlan.Run() after completing all TestStepBase.Run() methods in the TestPlan
        /// <remarks>Note that TestStep.PostPlan run is run in reverse order
        ///          For example, if you had three Tests (T1, T2, and T3), and T2 was disabled, then
        ///          PrePlanRun would run for T1 and T3 (in that order)
        ///          PostPlanRun would run for T3 and T1 (in that order)</remarks>
        /// </summary>
        void PostPlanRun();
 
        /// <summary>
        /// Unique ID used for storing references to test steps.  
        /// </summary>
        [XmlAttribute("Id")]
        [Browsable(false)]
        Guid Id { get; set; }
    }
 
    /// <summary>
    /// Search pattern to use while getting child steps.
    /// </summary>
    public enum TestStepSearch
    {
        /// <summary>
        /// All steps are wanted.
        /// </summary>
        All,
        /// <summary>
        /// Only enabled steps are wanted.
        /// </summary>
        EnabledOnly,
        /// <summary>
        /// Only disabled steps are wanted.
        /// </summary>
        NotEnabledOnly
    }
 
    internal static class ITestStepParentExtensions
    {
        /// <summary> Gets the step hierarchy starting from child to parent.
        /// Includes the test plan as the last item. </summary>
        public static IEnumerable<ITestStepParent> GetStepHierarchy(this ITestStepParent step)
        {
            for (ITestStepParent it = step; it != null; it = it.Parent)
                yield return it;
        }
        public static IEnumerable<ITestStepParent> GetParents(this ITestStepParent step)
         => GetStepHierarchy(step.Parent);
    }
}