PageRenderTime 34ms CodeModel.GetById 7ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/test_tools/simpletest/frames.php

http://prado3.googlecode.com/
PHP | 588 lines | 297 code | 38 blank | 253 comment | 47 complexity | 3dc311da7cc24a1791977c2c0ad2fb29 MD5 | raw file
Possible License(s): Apache-2.0, IPL-1.0, LGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * Base include file for SimpleTest
  4. * @package SimpleTest
  5. * @subpackage WebTester
  6. * @version $Id: frames.php 1398 2006-09-08 19:31:03Z xue $
  7. */
  8. /**#@+
  9. * include other SimpleTest class files
  10. */
  11. require_once(dirname(__FILE__) . '/page.php');
  12. require_once(dirname(__FILE__) . '/user_agent.php');
  13. /**#@-*/
  14. /**
  15. * A composite page. Wraps a frameset page and
  16. * adds subframes. The original page will be
  17. * mostly ignored. Implements the SimplePage
  18. * interface so as to be interchangeable.
  19. * @package SimpleTest
  20. * @subpackage WebTester
  21. */
  22. class SimpleFrameset {
  23. protected $_frameset;
  24. protected $_frames;
  25. protected $_focus;
  26. protected $_names;
  27. /**
  28. * Stashes the frameset page. Will make use of the
  29. * browser to fetch the sub frames recursively.
  30. * @param SimplePage $page Frameset page.
  31. */
  32. function SimpleFrameset($page) {
  33. $this->_frameset = $page;
  34. $this->_frames = array();
  35. $this->_focus = false;
  36. $this->_names = array();
  37. }
  38. /**
  39. * Adds a parsed page to the frameset.
  40. * @param SimplePage $page Frame page.
  41. * @param string $name Name of frame in frameset.
  42. * @access public
  43. */
  44. function addFrame($page, $name = false) {
  45. $this->_frames[] = $page;
  46. if ($name) {
  47. $this->_names[$name] = count($this->_frames) - 1;
  48. }
  49. }
  50. /**
  51. * Replaces existing frame with another. If the
  52. * frame is nested, then the call is passed down
  53. * one level.
  54. * @param array $path Path of frame in frameset.
  55. * @param SimplePage $page Frame source.
  56. * @access public
  57. */
  58. function setFrame($path, $page) {
  59. $name = array_shift($path);
  60. if (isset($this->_names[$name])) {
  61. $index = $this->_names[$name];
  62. } else {
  63. $index = $name - 1;
  64. }
  65. if (count($path) == 0) {
  66. $this->_frames[$index] = $page;
  67. return;
  68. }
  69. $this->_frames[$index]->setFrame($path, $page);
  70. }
  71. /**
  72. * Accessor for current frame focus. Will be
  73. * false if no frame has focus. Will have the nested
  74. * frame focus if any.
  75. * @return array Labels or indexes of nested frames.
  76. * @access public
  77. */
  78. function getFrameFocus() {
  79. if ($this->_focus === false) {
  80. return array();
  81. }
  82. return array_merge(
  83. array($this->_getPublicNameFromIndex($this->_focus)),
  84. $this->_frames[$this->_focus]->getFrameFocus());
  85. }
  86. /**
  87. * Turns an internal array index into the frames list
  88. * into a public name, or if none, then a one offset
  89. * index.
  90. * @param integer $subject Internal index.
  91. * @return integer/string Public name.
  92. * @access private
  93. */
  94. function _getPublicNameFromIndex($subject) {
  95. foreach ($this->_names as $name => $index) {
  96. if ($subject == $index) {
  97. return $name;
  98. }
  99. }
  100. return $subject + 1;
  101. }
  102. /**
  103. * Sets the focus by index. The integer index starts from 1.
  104. * If already focused and the target frame also has frames,
  105. * then the nested frame will be focused.
  106. * @param integer $choice Chosen frame.
  107. * @return boolean True if frame exists.
  108. * @access public
  109. */
  110. function setFrameFocusByIndex($choice) {
  111. if (is_integer($this->_focus)) {
  112. if ($this->_frames[$this->_focus]->hasFrames()) {
  113. return $this->_frames[$this->_focus]->setFrameFocusByIndex($choice);
  114. }
  115. }
  116. if (($choice < 1) || ($choice > count($this->_frames))) {
  117. return false;
  118. }
  119. $this->_focus = $choice - 1;
  120. return true;
  121. }
  122. /**
  123. * Sets the focus by name. If already focused and the
  124. * target frame also has frames, then the nested frame
  125. * will be focused.
  126. * @param string $name Chosen frame.
  127. * @return boolean True if frame exists.
  128. * @access public
  129. */
  130. function setFrameFocus($name) {
  131. if (is_integer($this->_focus)) {
  132. if ($this->_frames[$this->_focus]->hasFrames()) {
  133. return $this->_frames[$this->_focus]->setFrameFocus($name);
  134. }
  135. }
  136. if (in_array($name, array_keys($this->_names))) {
  137. $this->_focus = $this->_names[$name];
  138. return true;
  139. }
  140. return false;
  141. }
  142. /**
  143. * Clears the frame focus.
  144. * @access public
  145. */
  146. function clearFrameFocus() {
  147. $this->_focus = false;
  148. $this->_clearNestedFramesFocus();
  149. }
  150. /**
  151. * Clears the frame focus for any nested frames.
  152. * @access private
  153. */
  154. function _clearNestedFramesFocus() {
  155. for ($i = 0; $i < count($this->_frames); $i++) {
  156. $this->_frames[$i]->clearFrameFocus();
  157. }
  158. }
  159. /**
  160. * Test for the presence of a frameset.
  161. * @return boolean Always true.
  162. * @access public
  163. */
  164. function hasFrames() {
  165. return true;
  166. }
  167. /**
  168. * Accessor for frames information.
  169. * @return array/string Recursive hash of frame URL strings.
  170. * The key is either a numerical
  171. * index or the name attribute.
  172. * @access public
  173. */
  174. function getFrames() {
  175. $report = array();
  176. for ($i = 0; $i < count($this->_frames); $i++) {
  177. $report[$this->_getPublicNameFromIndex($i)] =
  178. $this->_frames[$i]->getFrames();
  179. }
  180. return $report;
  181. }
  182. /**
  183. * Accessor for raw text of either all the pages or
  184. * the frame in focus.
  185. * @return string Raw unparsed content.
  186. * @access public
  187. */
  188. function getRaw() {
  189. if (is_integer($this->_focus)) {
  190. return $this->_frames[$this->_focus]->getRaw();
  191. }
  192. $raw = '';
  193. for ($i = 0; $i < count($this->_frames); $i++) {
  194. $raw .= $this->_frames[$i]->getRaw();
  195. }
  196. return $raw;
  197. }
  198. /**
  199. * Accessor for plain text of either all the pages or
  200. * the frame in focus.
  201. * @return string Plain text content.
  202. * @access public
  203. */
  204. function getText() {
  205. if (is_integer($this->_focus)) {
  206. return $this->_frames[$this->_focus]->getText();
  207. }
  208. $raw = '';
  209. for ($i = 0; $i < count($this->_frames); $i++) {
  210. $raw .= ' ' . $this->_frames[$i]->getText();
  211. }
  212. return trim($raw);
  213. }
  214. /**
  215. * Accessor for last error.
  216. * @return string Error from last response.
  217. * @access public
  218. */
  219. function getTransportError() {
  220. if (is_integer($this->_focus)) {
  221. return $this->_frames[$this->_focus]->getTransportError();
  222. }
  223. return $this->_frameset->getTransportError();
  224. }
  225. /**
  226. * Request method used to fetch this frame.
  227. * @return string GET, POST or HEAD.
  228. * @access public
  229. */
  230. function getMethod() {
  231. if (is_integer($this->_focus)) {
  232. return $this->_frames[$this->_focus]->getMethod();
  233. }
  234. return $this->_frameset->getMethod();
  235. }
  236. /**
  237. * Original resource name.
  238. * @return SimpleUrl Current url.
  239. * @access public
  240. */
  241. function getUrl() {
  242. if (is_integer($this->_focus)) {
  243. $url = $this->_frames[$this->_focus]->getUrl();
  244. $url->setTarget($this->_getPublicNameFromIndex($this->_focus));
  245. } else {
  246. $url = $this->_frameset->getUrl();
  247. }
  248. return $url;
  249. }
  250. /**
  251. * Original request data.
  252. * @return mixed Sent content.
  253. * @access public
  254. */
  255. function getRequestData() {
  256. if (is_integer($this->_focus)) {
  257. return $this->_frames[$this->_focus]->getRequestData();
  258. }
  259. return $this->_frameset->getRequestData();
  260. }
  261. /**
  262. * Accessor for current MIME type.
  263. * @return string MIME type as string; e.g. 'text/html'
  264. * @access public
  265. */
  266. function getMimeType() {
  267. if (is_integer($this->_focus)) {
  268. return $this->_frames[$this->_focus]->getMimeType();
  269. }
  270. return $this->_frameset->getMimeType();
  271. }
  272. /**
  273. * Accessor for last response code.
  274. * @return integer Last HTTP response code received.
  275. * @access public
  276. */
  277. function getResponseCode() {
  278. if (is_integer($this->_focus)) {
  279. return $this->_frames[$this->_focus]->getResponseCode();
  280. }
  281. return $this->_frameset->getResponseCode();
  282. }
  283. /**
  284. * Accessor for last Authentication type. Only valid
  285. * straight after a challenge (401).
  286. * @return string Description of challenge type.
  287. * @access public
  288. */
  289. function getAuthentication() {
  290. if (is_integer($this->_focus)) {
  291. return $this->_frames[$this->_focus]->getAuthentication();
  292. }
  293. return $this->_frameset->getAuthentication();
  294. }
  295. /**
  296. * Accessor for last Authentication realm. Only valid
  297. * straight after a challenge (401).
  298. * @return string Name of security realm.
  299. * @access public
  300. */
  301. function getRealm() {
  302. if (is_integer($this->_focus)) {
  303. return $this->_frames[$this->_focus]->getRealm();
  304. }
  305. return $this->_frameset->getRealm();
  306. }
  307. /**
  308. * Accessor for outgoing header information.
  309. * @return string Header block.
  310. * @access public
  311. */
  312. function getRequest() {
  313. if (is_integer($this->_focus)) {
  314. return $this->_frames[$this->_focus]->getRequest();
  315. }
  316. return $this->_frameset->getRequest();
  317. }
  318. /**
  319. * Accessor for raw header information.
  320. * @return string Header block.
  321. * @access public
  322. */
  323. function getHeaders() {
  324. if (is_integer($this->_focus)) {
  325. return $this->_frames[$this->_focus]->getHeaders();
  326. }
  327. return $this->_frameset->getHeaders();
  328. }
  329. /**
  330. * Accessor for parsed title.
  331. * @return string Title or false if no title is present.
  332. * @access public
  333. */
  334. function getTitle() {
  335. return $this->_frameset->getTitle();
  336. }
  337. /**
  338. * Accessor for a list of all fixed links.
  339. * @return array List of urls with scheme of
  340. * http or https and hostname.
  341. * @access public
  342. */
  343. function getAbsoluteUrls() {
  344. if (is_integer($this->_focus)) {
  345. return $this->_frames[$this->_focus]->getAbsoluteUrls();
  346. }
  347. $urls = array();
  348. foreach ($this->_frames as $frame) {
  349. $urls = array_merge($urls, $frame->getAbsoluteUrls());
  350. }
  351. return array_values(array_unique($urls));
  352. }
  353. /**
  354. * Accessor for a list of all relative links.
  355. * @return array List of urls without hostname.
  356. * @access public
  357. */
  358. function getRelativeUrls() {
  359. if (is_integer($this->_focus)) {
  360. return $this->_frames[$this->_focus]->getRelativeUrls();
  361. }
  362. $urls = array();
  363. foreach ($this->_frames as $frame) {
  364. $urls = array_merge($urls, $frame->getRelativeUrls());
  365. }
  366. return array_values(array_unique($urls));
  367. }
  368. /**
  369. * Accessor for URLs by the link label. Label will match
  370. * regardess of whitespace issues and case.
  371. * @param string $label Text of link.
  372. * @return array List of links with that label.
  373. * @access public
  374. */
  375. function getUrlsByLabel($label) {
  376. if (is_integer($this->_focus)) {
  377. return $this->_tagUrlsWithFrame(
  378. $this->_frames[$this->_focus]->getUrlsByLabel($label),
  379. $this->_focus);
  380. }
  381. $urls = array();
  382. foreach ($this->_frames as $index => $frame) {
  383. $urls = array_merge(
  384. $urls,
  385. $this->_tagUrlsWithFrame(
  386. $frame->getUrlsByLabel($label),
  387. $index));
  388. }
  389. return $urls;
  390. }
  391. /**
  392. * Accessor for a URL by the id attribute. If in a frameset
  393. * then the first link found with that ID attribute is
  394. * returned only. Focus on a frame if you want one from
  395. * a specific part of the frameset.
  396. * @param string $id Id attribute of link.
  397. * @return string URL with that id.
  398. * @access public
  399. */
  400. function getUrlById($id) {
  401. foreach ($this->_frames as $index => $frame) {
  402. if ($url = $frame->getUrlById($id)) {
  403. if (! $url->gettarget()) {
  404. $url->setTarget($this->_getPublicNameFromIndex($index));
  405. }
  406. return $url;
  407. }
  408. }
  409. return false;
  410. }
  411. /**
  412. * Attaches the intended frame index to a list of URLs.
  413. * @param array $urls List of SimpleUrls.
  414. * @param string $frame Name of frame or index.
  415. * @return array List of tagged URLs.
  416. * @access private
  417. */
  418. function _tagUrlsWithFrame($urls, $frame) {
  419. $tagged = array();
  420. foreach ($urls as $url) {
  421. if (! $url->getTarget()) {
  422. $url->setTarget($this->_getPublicNameFromIndex($frame));
  423. }
  424. $tagged[] = $url;
  425. }
  426. return $tagged;
  427. }
  428. /**
  429. * Finds a held form by button label. Will only
  430. * search correctly built forms.
  431. * @param SimpleSelector $selector Button finder.
  432. * @return SimpleForm Form object containing
  433. * the button.
  434. * @access public
  435. */
  436. function &getFormBySubmit($selector) {
  437. $form = $this->_findForm('getFormBySubmit', $selector);
  438. return $form;
  439. }
  440. /**
  441. * Finds a held form by image using a selector.
  442. * Will only search correctly built forms. The first
  443. * form found either within the focused frame, or
  444. * across frames, will be the one returned.
  445. * @param SimpleSelector $selector Image finder.
  446. * @return SimpleForm Form object containing
  447. * the image.
  448. * @access public
  449. */
  450. function &getFormByImage($selector) {
  451. $form = $this->_findForm('getFormByImage', $selector);
  452. return $form;
  453. }
  454. /**
  455. * Finds a held form by the form ID. A way of
  456. * identifying a specific form when we have control
  457. * of the HTML code. The first form found
  458. * either within the focused frame, or across frames,
  459. * will be the one returned.
  460. * @param string $id Form label.
  461. * @return SimpleForm Form object containing the matching ID.
  462. * @access public
  463. */
  464. function &getFormById($id) {
  465. $form = $this->_findForm('getFormById', $id);
  466. return $form;
  467. }
  468. /**
  469. * General form finder. Will search all the frames or
  470. * just the one in focus.
  471. * @param string $method Method to use to find in a page.
  472. * @param string $attribute Label, name or ID.
  473. * @return SimpleForm Form object containing the matching ID.
  474. * @access private
  475. */
  476. function &_findForm($method, $attribute) {
  477. if (is_integer($this->_focus)) {
  478. $form = $this->_findFormInFrame(
  479. $this->_frames[$this->_focus],
  480. $this->_focus,
  481. $method,
  482. $attribute);
  483. return $form;
  484. }
  485. for ($i = 0; $i < count($this->_frames); $i++) {
  486. $form = $this->_findFormInFrame(
  487. $this->_frames[$i],
  488. $i,
  489. $method,
  490. $attribute);
  491. if ($form) {
  492. return $form;
  493. }
  494. }
  495. $null = null;
  496. return $null;
  497. }
  498. /**
  499. * Finds a form in a page using a form finding method. Will
  500. * also tag the form with the frame name it belongs in.
  501. * @param SimplePage $page Page content of frame.
  502. * @param integer $index Internal frame representation.
  503. * @param string $method Method to use to find in a page.
  504. * @param string $attribute Label, name or ID.
  505. * @return SimpleForm Form object containing the matching ID.
  506. * @access private
  507. */
  508. function &_findFormInFrame($page, $index, $method, $attribute) {
  509. $form = $this->_frames[$index]->$method($attribute);
  510. if (isset($form)) {
  511. $form->setDefaultTarget($this->_getPublicNameFromIndex($index));
  512. }
  513. return $form;
  514. }
  515. /**
  516. * Sets a field on each form in which the field is
  517. * available.
  518. * @param SimpleSelector $selector Field finder.
  519. * @param string $value Value to set field to.
  520. * @return boolean True if value is valid.
  521. * @access public
  522. */
  523. function setField($selector, $value) {
  524. if (is_integer($this->_focus)) {
  525. $this->_frames[$this->_focus]->setField($selector, $value);
  526. } else {
  527. for ($i = 0; $i < count($this->_frames); $i++) {
  528. $this->_frames[$i]->setField($selector, $value);
  529. }
  530. }
  531. }
  532. /**
  533. * Accessor for a form element value within a page.
  534. * @param SimpleSelector $selector Field finder.
  535. * @return string/boolean A string if the field is
  536. * present, false if unchecked
  537. * and null if missing.
  538. * @access public
  539. */
  540. function getField($selector) {
  541. for ($i = 0; $i < count($this->_frames); $i++) {
  542. $value = $this->_frames[$i]->getField($selector);
  543. if (isset($value)) {
  544. return $value;
  545. }
  546. }
  547. return null;
  548. }
  549. }
  550. ?>