Skip to content

Commit dedc50f

Browse files
committed
persist recorded targets alternatives, and show them in autocomplete, fixes #150
1 parent f4b3c85 commit dedc50f

File tree

6 files changed

+119
-3
lines changed

6 files changed

+119
-3
lines changed

packages/selenium-ide/src/neo/IO/SideeX/record.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export function recordCommand(command, target, value, index, select = false) {
4141
if (select) {
4242
UiState.selectCommand(newCommand);
4343
}
44+
45+
return newCommand;
4446
}
4547

4648
// for record module
@@ -65,7 +67,8 @@ export default function record(command, targets, value, insertBeforeLastCommand
6567
// double click removed the 2 clicks from before
6668
index -= 2;
6769
}
68-
recordCommand(command, targets[0][0], value, index);
70+
const newCommand = recordCommand(command, targets[0][0], value, index);
71+
newCommand.setTargets(targets);
6972
}
7073
}
7174

packages/selenium-ide/src/neo/__test__/models/Command.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,12 @@ describe("Command", () => {
5555
const command = new Command();
5656
command.setCommand();
5757
command.setTarget();
58+
command.setTargets();
5859
command.setValue();
5960
command.setComment();
6061
expect(command.command).toEqual("");
6162
expect(command.target).toEqual("");
63+
expect(command.targets.length).toBe(0);
6264
expect(command.value).toEqual("");
6365
expect(command.comment).toEqual("");
6466
});
@@ -67,6 +69,14 @@ describe("Command", () => {
6769
command.setTarget("a");
6870
expect(command.target).toBe("a");
6971
});
72+
it("should set the targets", () => {
73+
const command = new Command();
74+
command.setTargets([
75+
["button", "xpath"]
76+
]);
77+
expect(command.targets[0][0]).toBe("button");
78+
expect(command.targets[0][1]).toBe("xpath");
79+
});
7080
it("should set the value", () => {
7181
const command = new Command();
7282
command.setValue("123456");
@@ -95,6 +105,9 @@ describe("Command", () => {
95105
command.setComment("test");
96106
command.setCommand("open");
97107
command.setTarget("a");
108+
command.setTargets([
109+
["button", "xpath"]
110+
]);
98111
command.setValue("submit");
99112
command.toggleBreakpoint();
100113
const clone = command.clone();
@@ -103,6 +116,7 @@ describe("Command", () => {
103116
expect(clone.comment).toBe(command.comment);
104117
expect(clone.command).toBe(command.command);
105118
expect(clone.target).toBe(command.target);
119+
expect(clone.targets).toEqual(command.targets);
106120
expect(clone.value).toBe(command.value);
107121
expect(clone.isBreakpoint).toBeFalsy();
108122
});
@@ -113,13 +127,18 @@ describe("Command", () => {
113127
comment: "test",
114128
command: "open",
115129
target: "/",
130+
targets: [
131+
["button", "xpath"]
132+
],
116133
value: "test"
117134
};
118135
const command = Command.fromJS(jsRepresentation);
119136
expect(command.id).toBe(jsRepresentation.id);
120137
expect(command.comment).toBe(jsRepresentation.comment);
121138
expect(command.command).toBe(jsRepresentation.command);
122139
expect(command.target).toBe(jsRepresentation.target);
140+
expect(command.targets[0][0]).toBe("button");
141+
expect(command.targets[0][1]).toBe("xpath");
123142
expect(command.value).toBe(jsRepresentation.value);
124143
expect(command.isBreakpoint).toBeFalsy();
125144
expect(command instanceof Command).toBeTruthy();

packages/selenium-ide/src/neo/components/CommandForm/index.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { Commands } from "../../models/Command";
2323
import Input from "../FormInput";
2424
import TextArea from "../FormTextArea";
2525
import CommandInput from "../CommandInput";
26+
import TargetInput from "../TargetInput";
2627
import FlatButton from "../FlatButton";
2728
import { find, select } from "../../IO/SideeX/find-select";
2829
import "./style.css";
@@ -61,11 +62,12 @@ import "./style.css";
6162
disabled={!this.props.command}
6263
onChange={this.props.command ? this.props.command.setCommand : null} />
6364
<div className="target">
64-
<Input
65+
<TargetInput
6566
id="target"
6667
name="target"
6768
label="Target"
6869
value={this.props.command ? this.props.command.target : ""}
70+
targets={this.props.command.targets}
6971
disabled={!this.props.command}
7072
onChange={this.props.command ? this.props.command.setTarget : null} />
7173
<FlatButton
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
import React from "react";
19+
import PropTypes from "prop-types";
20+
import { PropTypes as MobxPropTypes } from "mobx-react";
21+
import AutoComplete from "../AutoComplete";
22+
import Input from "../FormInput";
23+
24+
export default class TargetInput extends React.Component {
25+
static propTypes = {
26+
name: PropTypes.string.isRequired,
27+
label: PropTypes.string.isRequired,
28+
targets: MobxPropTypes.arrayOrObservableArray,
29+
disabled: PropTypes.bool,
30+
value: PropTypes.string,
31+
onChange: PropTypes.func
32+
};
33+
render() {
34+
return (this.props.targets && this.props.targets.length ?
35+
<Input name={this.props.name} label={this.props.label}>
36+
<AutoComplete
37+
getItemValue={(item) => (
38+
item[0]
39+
)}
40+
items={this.props.targets.peek()}
41+
renderDefaultStyledItem={(item) =>
42+
<TargetSuggestion locator={item[0]} strategy={item[1]} />
43+
}
44+
value={this.props.value}
45+
inputProps={{ disabled: this.props.disabled }}
46+
onChange={(e) => { if (this.props.onChange) this.props.onChange(e.target.value); }}
47+
onSelect={(value) => { if (this.props.onChange) this.props.onChange(value); }}
48+
/>
49+
</Input> :
50+
<Input
51+
name={this.props.name}
52+
label={this.props.label}
53+
value={this.props.value}
54+
disabled={this.props.disabled}
55+
onChange={(e) => { if (this.props.onChange) this.props.onChange(e.target.value); }} />
56+
);
57+
}
58+
}
59+
60+
class TargetSuggestion extends React.Component {
61+
static propTypes = {
62+
locator: PropTypes.string.isRequired,
63+
strategy: PropTypes.string
64+
};
65+
render() {
66+
return (
67+
<span style={{
68+
display: "flex"
69+
}}>
70+
<span style={{
71+
flexGrow: "1",
72+
wordBreak: "break-word"
73+
}}>{this.props.locator}</span>
74+
{this.props.strategy && <span style={{
75+
color: "#929292",
76+
flexGrow: "initial",
77+
paddingLeft: "10px"
78+
}}>{this.props.strategy}</span>}
79+
</span>
80+
);
81+
}
82+
}

packages/selenium-ide/src/neo/models/Command.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
import { action, computed, observable } from "mobx";
18+
import { action, computed, observable, toJS } from "mobx";
1919
import uuidv4 from "uuid/v4";
2020

2121
export default class Command {
2222
id = null;
2323
@observable comment = "";
2424
@observable command;
2525
@observable target;
26+
@observable targets = [];
2627
@observable value;
2728
@observable isBreakpoint = false;
2829

@@ -60,6 +61,10 @@ export default class Command {
6061
this.target = target || "";
6162
}
6263

64+
@action.bound setTargets(targets = []) {
65+
this.targets.replace(targets);
66+
}
67+
6368
@action.bound setValue(value) {
6469
this.value = value ? value.replace(/\n/g, "\\n") : "";
6570
}
@@ -72,6 +77,7 @@ export default class Command {
7277
this.setComment(jsRep.comment);
7378
this.setCommand(jsRep.command);
7479
this.setTarget(jsRep.target);
80+
this.setTargets(jsRep.targets);
7581
this.setValue(jsRep.value);
7682
}
7783

@@ -81,6 +87,7 @@ export default class Command {
8187
comment: this.comment,
8288
command: this.command,
8389
target: this.target,
90+
targets: toJS(this.targets),
8491
value: this.value
8592
};
8693
}

packages/selenium-ide/src/neo/stores/seed.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ export default function seed(store, numberOfSuites = 5) {
6060
const firstClick = playbackTest.createCommand();
6161
firstClick.setCommand("click");
6262
firstClick.setTarget("link=enacted");
63+
firstClick.setTargets([
64+
["//div[@id='mw-content-text']/div/p[7]", "xpath:idRelative"]
65+
]);
6366
const secondClick = playbackTest.createCommand();
6467
secondClick.setCommand("clickAt");
6568
secondClick.setTarget("link=parliamentary systems");

0 commit comments

Comments
 (0)