Completed
Push — master ( 782892...5bf53f )
by Juan Francisco
03:56
created

FormManipulationTrait   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 20
c 3
b 0
f 0
lcom 1
cbo 1
dl 0
loc 158
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getValue() 0 5 1
A setValue() 0 10 2
A submitForm() 0 8 2
A boolToString() 0 6 2
A selectOption() 0 15 4
A inputCheckableControl() 0 12 3
A check() 0 5 1
A uncheck() 0 5 1
A isChecked() 0 11 2
A isSelected() 0 10 2
1
<?php
2
3
namespace Zumba\Mink\Driver;
4
5
use Behat\Mink\Exception\DriverException;
6
7
/**
8
 * Trait FormManipulationTrait
9
 * @package Zumba\Mink\Driver
10
 */
11
trait FormManipulationTrait {
12
13
14
  /**
15
   * Returns the value of a given xpath element
16
   * @param string $xpath
17
   * @return string
18
   * @throws DriverException
19
   */
20
  public function getValue($xpath) {
21
    $this->findElement($xpath, 1);
0 ignored issues
show
Bug introduced by
It seems like findElement() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
22
    $javascript = $this->javascriptTemplateRender("get_value.js.twig", array("xpath" => $xpath));
0 ignored issues
show
Bug introduced by
It seems like javascriptTemplateRender() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
23
    return $this->browser->evaluate($javascript);
0 ignored issues
show
Bug introduced by
The property browser does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
24
  }
25
26
  /**
27
   * @param string $xpath
28
   * @param string $value
29
   * @throws DriverException
30
   */
31
  public function setValue($xpath, $value) {
32
    $this->findElement($xpath, 1);
0 ignored issues
show
Bug introduced by
It seems like findElement() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
33
    //This stuff is BECAUSE the way the driver works for setting values when being checkboxes, radios, etc.
34
    if (is_bool($value)) {
35
      $value = $this->boolToString($value);
36
    }
37
38
    $javascript = $this->javascriptTemplateRender("set_value.js.twig", array("xpath" => $xpath, "value" => json_encode($value)));
0 ignored issues
show
Bug introduced by
It seems like javascriptTemplateRender() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
39
    $this->browser->evaluate($javascript);
40
  }
41
42
43
  /**
44
   * Submits a form given an xpath selector
45
   * @param string $xpath
46
   * @throws DriverException
47
   */
48
  public function submitForm($xpath) {
49
    $element = $this->findElement($xpath, 1);
0 ignored issues
show
Bug introduced by
It seems like findElement() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
50
    $tagName = $this->browser->tagName($element["page_id"], $element["ids"][0]);
51
    if (strcmp(strtolower($tagName), "form") !== 0) {
52
      throw new DriverException("Can not submit something that is not a form");
53
    }
54
    $this->browser->trigger($element["page_id"], $element["ids"][0], "submit");
55
  }
56
57
  /**
58
   * Helper method needed for twig and javascript stuff
59
   * @param $boolValue
60
   * @return string
61
   */
62
  protected function boolToString($boolValue) {
63
    if ($boolValue === true) {
64
      return "1";
65
    }
66
    return "0";
67
  }
68
69
  /**
70
   * Selects an option
71
   * @param string $xpath
72
   * @param string $value
73
   * @param bool   $multiple
74
   * @return bool
75
   * @throws DriverException
76
   */
77
  public function selectOption($xpath, $value, $multiple = false) {
78
    $element = $this->findElement($xpath, 1);
0 ignored issues
show
Bug introduced by
It seems like findElement() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
79
    $tagName = strtolower($this->browser->tagName($element["page_id"], $element["ids"][0]));
80
    $attributes = $this->browser->attributes($element["page_id"], $element["ids"][0]);
81
82
    if (!in_array($tagName, array("input", "select"))) {
83
      throw new DriverException(sprintf('Impossible to select an option on the element with XPath "%s" as it is not a select or radio input', $xpath));
84
    }
85
86
    if ($tagName === "input" && $attributes["type"] != "radio") {
87
      throw new DriverException(sprintf('Impossible to select an option on the element with XPath "%s" as it is not a select or radio input', $xpath));
88
    }
89
90
    return $this->browser->selectOption($element["page_id"], $element["ids"][0], $value, $multiple);
91
  }
92
93
  /**
94
   * Check control over an input element of radio or checkbox type
95
   * @param $xpath
96
   * @return bool
97
   * @throws DriverException
98
   */
99
  protected function inputCheckableControl($xpath) {
100
    $element = $this->findElement($xpath, 1);
0 ignored issues
show
Bug introduced by
It seems like findElement() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
101
    $tagName = strtolower($this->browser->tagName($element["page_id"], $element["ids"][0]));
102
    $attributes = $this->browser->attributes($element["page_id"], $element["ids"][0]);
103
    if ($tagName != "input") {
104
      throw new DriverException("Can not check when the element is not of the input type");
105
    }
106
    if (!in_array($attributes["type"], array("checkbox", "radio"))) {
107
      throw new DriverException("Can not check when the element is not checkbox or radio");
108
    }
109
    return true;
110
  }
111
112
  /**
113
   * We click on the checkbox or radio when possible and needed
114
   * @param string $xpath
115
   * @throws DriverException
116
   */
117
  public function check($xpath) {
118
    $this->inputCheckableControl($xpath);
119
    $javascript = $this->javascriptTemplateRender("check_element.js.twig", array("xpath" => $xpath, "check" => "true"));
0 ignored issues
show
Bug introduced by
It seems like javascriptTemplateRender() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
120
    $this->browser->evaluate($javascript);
121
  }
122
123
  /**
124
   * We click on the checkbox or radio when possible and needed
125
   * @param string $xpath
126
   * @throws DriverException
127
   */
128
  public function uncheck($xpath) {
129
    $this->inputCheckableControl($xpath);
130
    $javascript = $this->javascriptTemplateRender("check_element.js.twig", array("xpath" => $xpath, "check" => "false"));
0 ignored issues
show
Bug introduced by
It seems like javascriptTemplateRender() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
131
    $this->browser->evaluate($javascript);
132
  }
133
134
  /**
135
   * Checks if the radio or checkbox is checked
136
   * @param string $xpath
137
   * @return bool
138
   * @throws DriverException
139
   */
140
  public function isChecked($xpath) {
141
    $this->findElement($xpath, 1);
0 ignored issues
show
Bug introduced by
It seems like findElement() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
142
    $javascript = $this->javascriptTemplateRender("is_checked.js.twig", array("xpath" => $xpath));
0 ignored issues
show
Bug introduced by
It seems like javascriptTemplateRender() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
143
    $checked = $this->browser->evaluate($javascript);
144
145
    if ($checked === null) {
146
      throw new DriverException("Can not check when the element is not checkbox or radio");
147
    }
148
149
    return $checked;
150
  }
151
152
  /**
153
   * Checks if the option is selected or not
154
   * @param string $xpath
155
   * @return bool
156
   * @throws DriverException
157
   */
158
  public function isSelected($xpath) {
159
    $elements = $this->findElement($xpath, 1);
0 ignored issues
show
Bug introduced by
It seems like findElement() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
160
    $javascript = $this->javascriptTemplateRender("is_selected.js.twig", array("xpath" => $xpath));
0 ignored issues
show
Bug introduced by
It seems like javascriptTemplateRender() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
161
    $tagName = $this->browser->tagName($elements["page_id"], $elements["ids"][0]);
162
    if (strcmp(strtolower($tagName), "option") !== 0) {
163
      throw new DriverException("Can not assert on element that is not an option");
164
    }
165
166
    return $this->browser->evaluate($javascript);
167
  }
168
}
169