page_test.php 36KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. <?php
  2. // $Id: page_test.php 1782 2008-04-25 17:09:06Z pp11 $
  3. require_once(dirname(__FILE__) . '/../autorun.php');
  4. require_once(dirname(__FILE__) . '/../expectation.php');
  5. require_once(dirname(__FILE__) . '/../http.php');
  6. require_once(dirname(__FILE__) . '/../page.php');
  7. require_once(dirname(__FILE__) . '/../parser.php');
  8. Mock::generate('SimpleHtmlSaxParser');
  9. Mock::generate('SimplePage');
  10. Mock::generate('SimpleHttpResponse');
  11. Mock::generate('SimpleHttpHeaders');
  12. Mock::generate('SimplePageBuilder');
  13. Mock::generatePartial(
  14. 'SimplePageBuilder',
  15. 'PartialSimplePageBuilder',
  16. array('createPage', 'createParser'));
  17. class TestOfPageBuilder extends UnitTestCase {
  18. function testLink() {
  19. $tag = new SimpleAnchorTag(array('href' => 'http://somewhere'));
  20. $tag->addContent('Label');
  21. $page = new MockSimplePage();
  22. $page->expect('acceptTag', array($tag));
  23. $page->expectCallCount('acceptTag', 1);
  24. $builder = new PartialSimplePageBuilder();
  25. $builder->returns('createPage', $page);
  26. $builder->returns('createParser', new MockSimpleHtmlSaxParser());
  27. $builder->__construct();
  28. $builder->parse(new MockSimpleHttpResponse());
  29. $this->assertTrue($builder->startElement(
  30. 'a',
  31. array('href' => 'http://somewhere')));
  32. $this->assertTrue($builder->addContent('Label'));
  33. $this->assertTrue($builder->endElement('a'));
  34. }
  35. function testLinkWithId() {
  36. $tag = new SimpleAnchorTag(array("href" => "http://somewhere", "id" => "44"));
  37. $tag->addContent("Label");
  38. $page = new MockSimplePage();
  39. $page->expect("acceptTag", array($tag));
  40. $page->expectCallCount("acceptTag", 1);
  41. $builder = new PartialSimplePageBuilder();
  42. $builder->returns('createPage', $page);
  43. $builder->returns('createParser', new MockSimpleHtmlSaxParser());
  44. $builder->__construct();
  45. $builder->parse(new MockSimpleHttpResponse());
  46. $this->assertTrue($builder->startElement(
  47. "a",
  48. array("href" => "http://somewhere", "id" => "44")));
  49. $this->assertTrue($builder->addContent("Label"));
  50. $this->assertTrue($builder->endElement("a"));
  51. }
  52. function testLinkExtraction() {
  53. $tag = new SimpleAnchorTag(array("href" => "http://somewhere"));
  54. $tag->addContent("Label");
  55. $page = new MockSimplePage();
  56. $page->expect("acceptTag", array($tag));
  57. $page->expectCallCount("acceptTag", 1);
  58. $builder = new PartialSimplePageBuilder();
  59. $builder->returns('createPage', $page);
  60. $builder->returns('createParser', new MockSimpleHtmlSaxParser());
  61. $builder->__construct();
  62. $builder->parse(new MockSimpleHttpResponse());
  63. $this->assertTrue($builder->addContent("Starting stuff"));
  64. $this->assertTrue($builder->startElement(
  65. "a",
  66. array("href" => "http://somewhere")));
  67. $this->assertTrue($builder->addContent("Label"));
  68. $this->assertTrue($builder->endElement("a"));
  69. $this->assertTrue($builder->addContent("Trailing stuff"));
  70. }
  71. function testMultipleLinks() {
  72. $a1 = new SimpleAnchorTag(array("href" => "http://somewhere"));
  73. $a1->addContent("1");
  74. $a2 = new SimpleAnchorTag(array("href" => "http://elsewhere"));
  75. $a2->addContent("2");
  76. $page = new MockSimplePage();
  77. $page->expectAt(0, "acceptTag", array($a1));
  78. $page->expectAt(1, "acceptTag", array($a2));
  79. $page->expectCallCount("acceptTag", 2);
  80. $builder = new PartialSimplePageBuilder();
  81. $builder->returns('createPage', $page);
  82. $builder->returns('createParser', new MockSimpleHtmlSaxParser());
  83. $builder->__construct();
  84. $builder->parse(new MockSimpleHttpResponse());
  85. $builder->startElement("a", array("href" => "http://somewhere"));
  86. $builder->addContent("1");
  87. $builder->endElement("a");
  88. $builder->addContent("Padding");
  89. $builder->startElement("a", array("href" => "http://elsewhere"));
  90. $builder->addContent("2");
  91. $builder->endElement("a");
  92. }
  93. function testTitle() {
  94. $tag = new SimpleTitleTag(array());
  95. $tag->addContent("HereThere");
  96. $page = new MockSimplePage();
  97. $page->expect("acceptTag", array($tag));
  98. $page->expectCallCount("acceptTag", 1);
  99. $builder = new PartialSimplePageBuilder();
  100. $builder->returns('createPage', $page);
  101. $builder->returns('createParser', new MockSimpleHtmlSaxParser());
  102. $builder->__construct();
  103. $builder->parse(new MockSimpleHttpResponse());
  104. $builder->startElement("title", array());
  105. $builder->addContent("Here");
  106. $builder->addContent("There");
  107. $builder->endElement("title");
  108. }
  109. function testForm() {
  110. $page = new MockSimplePage();
  111. $page->expectOnce("acceptFormStart", array(new SimpleFormTag(array())));
  112. $page->expectOnce("acceptFormEnd", array());
  113. $builder = new PartialSimplePageBuilder();
  114. $builder->returns('createPage', $page);
  115. $builder->returns('createParser', new MockSimpleHtmlSaxParser());
  116. $builder->__construct();
  117. $builder->parse(new MockSimpleHttpResponse());
  118. $builder->startElement("form", array());
  119. $builder->addContent("Stuff");
  120. $builder->endElement("form");
  121. }
  122. }
  123. class TestOfPageParsing extends UnitTestCase {
  124. function testParseMechanics() {
  125. $parser = new MockSimpleHtmlSaxParser();
  126. $parser->expectOnce('parse', array('stuff'));
  127. $page = new MockSimplePage();
  128. $page->expectOnce('acceptPageEnd');
  129. $builder = new PartialSimplePageBuilder();
  130. $builder->returns('createPage', $page);
  131. $builder->returns('createParser', $parser);
  132. $builder->__construct();
  133. $response = new MockSimpleHttpResponse();
  134. $response->setReturnValue('getContent', 'stuff');
  135. $builder->parse($response);
  136. }
  137. }
  138. class TestOfPageInterface extends UnitTestCase {
  139. function testInterfaceOnEmptyPage() {
  140. $page = new SimplePage();
  141. $this->assertEqual($page->getTransportError(), 'No page fetched yet');
  142. $this->assertIdentical($page->getRaw(), false);
  143. $this->assertIdentical($page->getHeaders(), false);
  144. $this->assertIdentical($page->getMimeType(), false);
  145. $this->assertIdentical($page->getResponseCode(), false);
  146. $this->assertIdentical($page->getAuthentication(), false);
  147. $this->assertIdentical($page->getRealm(), false);
  148. $this->assertFalse($page->hasFrames());
  149. $this->assertIdentical($page->getUrls(), array());
  150. $this->assertIdentical($page->getTitle(), false);
  151. }
  152. }
  153. class TestOfPageHeaders extends UnitTestCase {
  154. function testUrlAccessor() {
  155. $headers = new MockSimpleHttpHeaders();
  156. $response = new MockSimpleHttpResponse();
  157. $response->setReturnValue('getHeaders', $headers);
  158. $response->setReturnValue('getMethod', 'POST');
  159. $response->setReturnValue('getUrl', new SimpleUrl('here'));
  160. $response->setReturnValue('getRequestData', array('a' => 'A'));
  161. $page = new SimplePage($response);
  162. $this->assertEqual($page->getMethod(), 'POST');
  163. $this->assertEqual($page->getUrl(), new SimpleUrl('here'));
  164. $this->assertEqual($page->getRequestData(), array('a' => 'A'));
  165. }
  166. function testTransportError() {
  167. $response = new MockSimpleHttpResponse();
  168. $response->setReturnValue('getError', 'Ouch');
  169. $page = new SimplePage($response);
  170. $this->assertEqual($page->getTransportError(), 'Ouch');
  171. }
  172. function testHeadersAccessor() {
  173. $headers = new MockSimpleHttpHeaders();
  174. $headers->setReturnValue('getRaw', 'My: Headers');
  175. $response = new MockSimpleHttpResponse();
  176. $response->setReturnValue('getHeaders', $headers);
  177. $page = new SimplePage($response);
  178. $this->assertEqual($page->getHeaders(), 'My: Headers');
  179. }
  180. function testMimeAccessor() {
  181. $headers = new MockSimpleHttpHeaders();
  182. $headers->setReturnValue('getMimeType', 'text/html');
  183. $response = new MockSimpleHttpResponse();
  184. $response->setReturnValue('getHeaders', $headers);
  185. $page = new SimplePage($response);
  186. $this->assertEqual($page->getMimeType(), 'text/html');
  187. }
  188. function testResponseAccessor() {
  189. $headers = new MockSimpleHttpHeaders();
  190. $headers->setReturnValue('getResponseCode', 301);
  191. $response = new MockSimpleHttpResponse();
  192. $response->setReturnValue('getHeaders', $headers);
  193. $page = new SimplePage($response);
  194. $this->assertIdentical($page->getResponseCode(), 301);
  195. }
  196. function testAuthenticationAccessors() {
  197. $headers = new MockSimpleHttpHeaders();
  198. $headers->setReturnValue('getAuthentication', 'Basic');
  199. $headers->setReturnValue('getRealm', 'Secret stuff');
  200. $response = new MockSimpleHttpResponse();
  201. $response->setReturnValue('getHeaders', $headers);
  202. $page = new SimplePage($response);
  203. $this->assertEqual($page->getAuthentication(), 'Basic');
  204. $this->assertEqual($page->getRealm(), 'Secret stuff');
  205. }
  206. }
  207. class TestOfHtmlPage extends UnitTestCase {
  208. function testRawAccessor() {
  209. $response = new MockSimpleHttpResponse();
  210. $response->setReturnValue('getContent', 'Raw HTML');
  211. $page = new SimplePage($response);
  212. $this->assertEqual($page->getRaw(), 'Raw HTML');
  213. }
  214. function testTextAccessor() {
  215. $response = new MockSimpleHttpResponse();
  216. $response->setReturnValue('getContent', '<b>Some</b> &quot;messy&quot; HTML');
  217. $page = new SimplePage($response);
  218. $this->assertEqual($page->getText(), 'Some "messy" HTML');
  219. }
  220. function testNoLinks() {
  221. $page = new SimplePage(new MockSimpleHttpResponse());
  222. $this->assertIdentical($page->getUrls(), array());
  223. $this->assertIdentical($page->getUrlsByLabel('Label'), array());
  224. }
  225. function testAddAbsoluteLink() {
  226. $link = new SimpleAnchorTag(array('href' => 'http://somewhere.com'));
  227. $link->addContent('Label');
  228. $page = new SimplePage(new MockSimpleHttpResponse());
  229. $page->AcceptTag($link);
  230. $this->assertEqual(
  231. $page->getUrlsByLabel('Label'),
  232. array(new SimpleUrl('http://somewhere.com')));
  233. }
  234. function testAddStrictRelativeLink() {
  235. $link = new SimpleAnchorTag(array('href' => './somewhere.php'));
  236. $link->addContent('Label');
  237. $response = new MockSimpleHttpResponse();
  238. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  239. $page = new SimplePage($response);
  240. $page->AcceptTag($link);
  241. $this->assertEqual(
  242. $page->getUrlsByLabel('Label'),
  243. array(new SimpleUrl('http://host/somewhere.php')));
  244. }
  245. function testAddBareRelativeLink() {
  246. $response = new MockSimpleHttpResponse();
  247. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  248. $page = new SimplePage($response);
  249. $page->AcceptTag(new SimpleAnchorTag(array('href' => 'somewhere.php')));
  250. $this->assertIdentical($page->getUrls(), array('http://host/somewhere.php'));
  251. }
  252. function testAddRelativeLinkWithBaseTag() {
  253. $link = new SimpleAnchorTag(array('href' => 'somewhere.php'));
  254. $link->addContent('Label');
  255. $response = new MockSimpleHttpResponse();
  256. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  257. $page = new SimplePage($response);
  258. $page->AcceptTag($link);
  259. $base = new SimpleBaseTag(array('href' => 'www.lastcraft.com/stuff/'));
  260. $page->AcceptTag($base);
  261. $this->assertEqual(
  262. $page->getUrlsByLabel('Label'),
  263. array(new SimpleUrl('www.lastcraft.com/stuff/somewhere.php')));
  264. }
  265. function testAddAbsoluteLinkWithBaseTag() {
  266. $link = new SimpleAnchorTag(array('href' => 'http://here.com/somewhere.php'));
  267. $link->addContent('Label');
  268. $response = new MockSimpleHttpResponse();
  269. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  270. $page = new SimplePage($response);
  271. $page->AcceptTag($link);
  272. $base = new SimpleBaseTag(array('href' => 'www.lastcraft.com/stuff/'));
  273. $page->AcceptTag($base);
  274. $this->assertEqual(
  275. $page->getUrlsByLabel('Label'),
  276. array(new SimpleUrl('http://here.com/somewhere.php')));
  277. }
  278. function testLinkIds() {
  279. $link = new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
  280. $link->addContent('Label');
  281. $response = new MockSimpleHttpResponse();
  282. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  283. $page = new SimplePage($response);
  284. $page->AcceptTag($link);
  285. $this->assertEqual(
  286. $page->getUrlsByLabel('Label'),
  287. array(new SimpleUrl('http://host/somewhere.php')));
  288. $this->assertFalse($page->getUrlById(0));
  289. $this->assertEqual(
  290. $page->getUrlById(33),
  291. new SimpleUrl('http://host/somewhere.php'));
  292. }
  293. function testFindLinkWithNormalisation() {
  294. $link = new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
  295. $link->addContent(' <em>Long &amp; thin</em> ');
  296. $response = new MockSimpleHttpResponse();
  297. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  298. $page = new SimplePage($response);
  299. $page->AcceptTag($link);
  300. $this->assertEqual(
  301. $page->getUrlsByLabel('Long & thin'),
  302. array(new SimpleUrl('http://host/somewhere.php')));
  303. }
  304. function testFindLinkWithImage() {
  305. $link = new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
  306. $link->addContent('<img src="pic.jpg" alt="&lt;A picture&gt;">');
  307. $response = new MockSimpleHttpResponse();
  308. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  309. $page = new SimplePage($response);
  310. $page->AcceptTag($link);
  311. $this->assertEqual(
  312. $page->getUrlsByLabel('<A picture>'),
  313. array(new SimpleUrl('http://host/somewhere.php')));
  314. }
  315. function testTitleSetting() {
  316. $title = new SimpleTitleTag(array());
  317. $title->addContent('Title');
  318. $page = new SimplePage(new MockSimpleHttpResponse());
  319. $page->AcceptTag($title);
  320. $this->assertEqual($page->getTitle(), 'Title');
  321. }
  322. function testFramesetAbsence() {
  323. $url = new SimpleUrl('here');
  324. $response = new MockSimpleHttpResponse();
  325. $response->setReturnValue('getUrl', $url);
  326. $page = new SimplePage($response);
  327. $this->assertFalse($page->hasFrames());
  328. $this->assertIdentical($page->getFrameset(), false);
  329. }
  330. function testHasEmptyFrameset() {
  331. $page = new SimplePage(new MockSimpleHttpResponse());
  332. $page->acceptFramesetStart(new SimpleTag('frameset', array()));
  333. $page->acceptFramesetEnd();
  334. $this->assertTrue($page->hasFrames());
  335. $this->assertIdentical($page->getFrameset(), array());
  336. }
  337. function testFramesInPage() {
  338. $response = new MockSimpleHttpResponse();
  339. $response->setReturnValue('getUrl', new SimpleUrl('http://here'));
  340. $page = new SimplePage($response);
  341. $page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
  342. $page->acceptFramesetStart(new SimpleTag('frameset', array()));
  343. $page->acceptFrame(new SimpleFrameTag(array('src' => '2.html')));
  344. $page->acceptFrame(new SimpleFrameTag(array('src' => '3.html')));
  345. $page->acceptFramesetEnd();
  346. $page->acceptFrame(new SimpleFrameTag(array('src' => '4.html')));
  347. $this->assertTrue($page->hasFrames());
  348. $this->assertIdentical($page->getFrameset(), array(
  349. 1 => new SimpleUrl('http://here/2.html'),
  350. 2 => new SimpleUrl('http://here/3.html')));
  351. }
  352. function testNamedFramesInPage() {
  353. $response = new MockSimpleHttpResponse();
  354. $response->setReturnValue('getUrl', new SimpleUrl('http://here'));
  355. $page = new SimplePage($response);
  356. $page->acceptFramesetStart(new SimpleTag('frameset', array()));
  357. $page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
  358. $page->acceptFrame(new SimpleFrameTag(array('src' => '2.html', 'name' => 'A')));
  359. $page->acceptFrame(new SimpleFrameTag(array('src' => '3.html', 'name' => 'B')));
  360. $page->acceptFrame(new SimpleFrameTag(array('src' => '4.html')));
  361. $page->acceptFramesetEnd();
  362. $this->assertTrue($page->hasFrames());
  363. $this->assertIdentical($page->getFrameset(), array(
  364. 1 => new SimpleUrl('http://here/1.html'),
  365. 'A' => new SimpleUrl('http://here/2.html'),
  366. 'B' => new SimpleUrl('http://here/3.html'),
  367. 4 => new SimpleUrl('http://here/4.html')));
  368. }
  369. function testRelativeFramesRespectBaseTag() {
  370. $response = new MockSimpleHttpResponse();
  371. $response->setReturnValue('getUrl', new SimpleUrl('http://here.com/'));
  372. $page = new SimplePage($response);
  373. $base = new SimpleBaseTag(array('href' => 'https://there.com/stuff/'));
  374. $page->AcceptTag($base);
  375. $page->acceptFramesetStart(new SimpleTag('frameset', array()));
  376. $page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
  377. $page->acceptFramesetEnd();
  378. $this->assertIdentical(
  379. $page->getFrameset(),
  380. array(1 => new SimpleUrl('https://there.com/stuff/1.html')));
  381. }
  382. }
  383. class TestOfFormsCreatedFromEventStream extends UnitTestCase {
  384. function testFormCanBeSubmitted() {
  385. $page = new SimplePage(new MockSimpleHttpResponse());
  386. $page->acceptFormStart(
  387. new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php')));
  388. $page->AcceptTag(
  389. new SimpleSubmitTag(array('type' => 'submit', 'name' => 's')));
  390. $page->acceptFormEnd();
  391. $form = &$page->getFormBySubmit(new SimpleByLabel('Submit'));
  392. $this->assertEqual(
  393. $form->submitButton(new SimpleByLabel('Submit')),
  394. new SimpleGetEncoding(array('s' => 'Submit')));
  395. }
  396. function testInputFieldCanBeReadBack() {
  397. $page = new SimplePage(new MockSimpleHttpResponse());
  398. $page->acceptFormStart(
  399. new SimpleFormTag(array("method" => "GET", "action" => "here.php")));
  400. $page->AcceptTag(
  401. new SimpleTextTag(array("type" => "text", "name" => "a", "value" => "A")));
  402. $page->AcceptTag(
  403. new SimpleSubmitTag(array("type" => "submit", "name" => "s")));
  404. $page->acceptFormEnd();
  405. $this->assertEqual($page->getField(new SimpleByName('a')), 'A');
  406. }
  407. function testInputFieldCanBeReadBackByLabel() {
  408. $label = new SimpleLabelTag(array());
  409. $page = new SimplePage(new MockSimpleHttpResponse());
  410. $page->acceptFormStart(
  411. new SimpleFormTag(array("method" => "GET", "action" => "here.php")));
  412. $page->acceptLabelStart($label);
  413. $label->addContent('l');
  414. $page->AcceptTag(
  415. new SimpleTextTag(array("type" => "text", "name" => "a", "value" => "A")));
  416. $page->acceptLabelEnd();
  417. $page->AcceptTag(
  418. new SimpleSubmitTag(array("type" => "submit", "name" => "s")));
  419. $page->acceptFormEnd();
  420. $this->assertEqual($page->getField(new SimpleByLabel('l')), 'A');
  421. }
  422. }
  423. class TestOfPageScraping extends UnitTestCase {
  424. function parse($response) {
  425. $builder = new SimplePageBuilder();
  426. $page = $builder->parse($response);
  427. return $page;
  428. }
  429. function testEmptyPage() {
  430. $page = new SimplePage(new MockSimpleHttpResponse());
  431. $this->assertIdentical($page->getUrls(), array());
  432. $this->assertIdentical($page->getTitle(), false);
  433. }
  434. function testUninterestingPage() {
  435. $response = new MockSimpleHttpResponse();
  436. $response->setReturnValue('getContent', '<html><body><p>Stuff</p></body></html>');
  437. $page = $this->parse($response);
  438. $this->assertIdentical($page->getUrls(), array());
  439. }
  440. function testLinksPage() {
  441. $raw = '<html>';
  442. $raw .= '<a href="there.html">There</a>';
  443. $raw .= '<a href="http://there.com/that.html" id="0">That page</a>';
  444. $raw .= '</html>';
  445. $response = new MockSimpleHttpResponse();
  446. $response->setReturnValue('getContent', $raw);
  447. $response->setReturnValue('getUrl', new SimpleUrl('http://www.here.com/a/index.html'));
  448. $page = $this->parse($response);
  449. $this->assertIdentical(
  450. $page->getUrls(),
  451. array('http://www.here.com/a/there.html', 'http://there.com/that.html'));
  452. $this->assertIdentical(
  453. $page->getUrlsByLabel('There'),
  454. array(new SimpleUrl('http://www.here.com/a/there.html')));
  455. $this->assertEqual(
  456. $page->getUrlById('0'),
  457. new SimpleUrl('http://there.com/that.html'));
  458. }
  459. function testTitle() {
  460. $response = new MockSimpleHttpResponse();
  461. $response->setReturnValue('getContent', '<html><head><title>Me</title></head></html>');
  462. $page = $this->parse($response);
  463. $this->assertEqual($page->getTitle(), 'Me');
  464. }
  465. function testNastyTitle() {
  466. $response = new MockSimpleHttpResponse();
  467. $response->setReturnValue(
  468. 'getContent',
  469. '<html><head><Title> <b>Me&amp;Me </TITLE></b></head></html>');
  470. $page = $this->parse($response);
  471. $this->assertEqual($page->getTitle(), "Me&Me");
  472. }
  473. function testCompleteForm() {
  474. $response = new MockSimpleHttpResponse();
  475. $response->setReturnValue('getContent',
  476. '<html><head><form>' .
  477. '<input type="text" name="here" value="Hello">' .
  478. '</form></head></html>');
  479. $page = $this->parse($response);
  480. $this->assertEqual($page->getField(new SimpleByName('here')), "Hello");
  481. }
  482. function testUnclosedForm() {
  483. $response = new MockSimpleHttpResponse();
  484. $response->setReturnValue('getContent',
  485. '<html><head><form>' .
  486. '<input type="text" name="here" value="Hello">' .
  487. '</head></html>');
  488. $page = $this->parse($response);
  489. $this->assertEqual($page->getField(new SimpleByName('here')), "Hello");
  490. }
  491. function testEmptyFrameset() {
  492. $response = new MockSimpleHttpResponse();
  493. $response->setReturnValue(
  494. 'getContent',
  495. '<html><frameset></frameset></html>');
  496. $page = $this->parse($response);
  497. $this->assertTrue($page->hasFrames());
  498. $this->assertIdentical($page->getFrameset(), array());
  499. }
  500. function testSingleFrame() {
  501. $response = new MockSimpleHttpResponse();
  502. $response->setReturnValue(
  503. 'getContent',
  504. '<html><frameset><frame src="a.html"></frameset></html>');
  505. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  506. $page = $this->parse($response);
  507. $this->assertTrue($page->hasFrames());
  508. $this->assertIdentical(
  509. $page->getFrameset(),
  510. array(1 => new SimpleUrl('http://host/a.html')));
  511. }
  512. function testSingleFrameInNestedFrameset() {
  513. $response = new MockSimpleHttpResponse();
  514. $response->setReturnValue('getContent',
  515. '<html><frameset><frameset>' .
  516. '<frame src="a.html">' .
  517. '</frameset></frameset></html>');
  518. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  519. $page = $this->parse($response);
  520. $this->assertTrue($page->hasFrames());
  521. $this->assertIdentical(
  522. $page->getFrameset(),
  523. array(1 => new SimpleUrl('http://host/a.html')));
  524. }
  525. function testFrameWithNoSource() {
  526. $response = new MockSimpleHttpResponse();
  527. $response->setReturnValue(
  528. 'getContent',
  529. '<html><frameset><frame></frameset></html>');
  530. $page = $this->parse($response);
  531. $this->assertTrue($page->hasFrames());
  532. $this->assertIdentical($page->getFrameset(), array());
  533. }
  534. function testFramesCollectedWithNestedFramesetTags() {
  535. $response = new MockSimpleHttpResponse();
  536. $response->setReturnValue('getContent',
  537. '<html><frameset>' .
  538. '<frame src="a.html">' .
  539. '<frameset><frame src="b.html"></frameset>' .
  540. '<frame src="c.html">' .
  541. '</frameset></html>');
  542. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  543. $page = $this->parse($response);
  544. $this->assertTrue($page->hasFrames());
  545. $this->assertIdentical($page->getFrameset(), array(
  546. 1 => new SimpleUrl('http://host/a.html'),
  547. 2 => new SimpleUrl('http://host/b.html'),
  548. 3 => new SimpleUrl('http://host/c.html')));
  549. }
  550. function testNamedFrames() {
  551. $response = new MockSimpleHttpResponse();
  552. $response->setReturnValue('getContent',
  553. '<html><frameset>' .
  554. '<frame src="a.html">' .
  555. '<frame name="_one" src="b.html">' .
  556. '<frame src="c.html">' .
  557. '<frame src="d.html" name="_two">' .
  558. '</frameset></html>');
  559. $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
  560. $page = $this->parse($response);
  561. $this->assertTrue($page->hasFrames());
  562. $this->assertIdentical($page->getFrameset(), array(
  563. 1 => new SimpleUrl('http://host/a.html'),
  564. '_one' => new SimpleUrl('http://host/b.html'),
  565. 3 => new SimpleUrl('http://host/c.html'),
  566. '_two' => new SimpleUrl('http://host/d.html')));
  567. }
  568. function testFindFormByLabel() {
  569. $response = new MockSimpleHttpResponse();
  570. $response->setReturnValue(
  571. 'getContent',
  572. '<html><head><form><input type="submit"></form></head></html>');
  573. $page = $this->parse($response);
  574. $this->assertNull($page->getFormBySubmit(new SimpleByLabel('submit')));
  575. $this->assertNull($page->getFormBySubmit(new SimpleByName('submit')));
  576. $this->assertIsA(
  577. $page->getFormBySubmit(new SimpleByLabel('Submit')),
  578. 'SimpleForm');
  579. }
  580. function testConfirmSubmitAttributesAreCaseSensitive() {
  581. $response = new MockSimpleHttpResponse();
  582. $response->setReturnValue(
  583. 'getContent',
  584. '<html><head><FORM><INPUT TYPE="SUBMIT" NAME="S" VALUE="S"></FORM></head></html>');
  585. $page = $this->parse($response);
  586. $this->assertIsA(
  587. $page->getFormBySubmit(new SimpleByName('S')),
  588. 'SimpleForm');
  589. $this->assertIsA(
  590. $page->getFormBySubmit(new SimpleByLabel('S')),
  591. 'SimpleForm');
  592. }
  593. function testFindFormByImage() {
  594. $response = new MockSimpleHttpResponse();
  595. $response->setReturnValue('getContent',
  596. '<html><head><form>' .
  597. '<input type="image" id=100 alt="Label" name="me">' .
  598. '</form></head></html>');
  599. $page = $this->parse($response);
  600. $this->assertIsA(
  601. $page->getFormByImage(new SimpleByLabel('Label')),
  602. 'SimpleForm');
  603. $this->assertIsA(
  604. $page->getFormByImage(new SimpleByName('me')),
  605. 'SimpleForm');
  606. $this->assertIsA(
  607. $page->getFormByImage(new SimpleById(100)),
  608. 'SimpleForm');
  609. }
  610. function testFindFormByButtonTag() {
  611. $response = new MockSimpleHttpResponse();
  612. $response->setReturnValue('getContent',
  613. '<html><head><form>' .
  614. '<button type="submit" name="b" value="B">BBB</button>' .
  615. '</form></head></html>');
  616. $page = $this->parse($response);
  617. $this->assertNull($page->getFormBySubmit(new SimpleByLabel('b')));
  618. $this->assertNull($page->getFormBySubmit(new SimpleByLabel('B')));
  619. $this->assertIsA(
  620. $page->getFormBySubmit(new SimpleByName('b')),
  621. 'SimpleForm');
  622. $this->assertIsA(
  623. $page->getFormBySubmit(new SimpleByLabel('BBB')),
  624. 'SimpleForm');
  625. }
  626. function testFindFormById() {
  627. $response = new MockSimpleHttpResponse();
  628. $response->setReturnValue(
  629. 'getContent',
  630. '<html><head><form id="55"><input type="submit"></form></head></html>');
  631. $page = $this->parse($response);
  632. $this->assertNull($page->getFormById(54));
  633. $this->assertIsA($page->getFormById(55), 'SimpleForm');
  634. }
  635. function testReadingTextField() {
  636. $response = new MockSimpleHttpResponse();
  637. $response->setReturnValue('getContent',
  638. '<html><head><form>' .
  639. '<input type="text" name="a">' .
  640. '<input type="text" name="b" value="bbb" id=3>' .
  641. '</form></head></html>');
  642. $page = $this->parse($response);
  643. $this->assertNull($page->getField(new SimpleByName('missing')));
  644. $this->assertIdentical($page->getField(new SimpleByName('a')), '');
  645. $this->assertIdentical($page->getField(new SimpleByName('b')), 'bbb');
  646. }
  647. function testReadingTextFieldIsCaseInsensitive() {
  648. $response = new MockSimpleHttpResponse();
  649. $response->setReturnValue('getContent',
  650. '<html><head><FORM>' .
  651. '<INPUT TYPE="TEXT" NAME="a">' .
  652. '<INPUT TYPE="TEXT" NAME="b" VALUE="bbb" id=3>' .
  653. '</FORM></head></html>');
  654. $page = $this->parse($response);
  655. $this->assertNull($page->getField(new SimpleByName('missing')));
  656. $this->assertIdentical($page->getField(new SimpleByName('a')), '');
  657. $this->assertIdentical($page->getField(new SimpleByName('b')), 'bbb');
  658. }
  659. function testSettingTextField() {
  660. $response = new MockSimpleHttpResponse();
  661. $response->setReturnValue('getContent',
  662. '<html><head><form>' .
  663. '<input type="text" name="a">' .
  664. '<input type="text" name="b" id=3>' .
  665. '<input type="submit">' .
  666. '</form></head></html>');
  667. $page = $this->parse($response);
  668. $this->assertTrue($page->setField(new SimpleByName('a'), 'aaa'));
  669. $this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
  670. $this->assertTrue($page->setField(new SimpleById(3), 'bbb'));
  671. $this->assertEqual($page->getField(new SimpleBYId(3)), 'bbb');
  672. $this->assertFalse($page->setField(new SimpleByName('z'), 'zzz'));
  673. $this->assertNull($page->getField(new SimpleByName('z')));
  674. }
  675. function testSettingTextFieldByEnclosingLabel() {
  676. $response = new MockSimpleHttpResponse();
  677. $response->setReturnValue('getContent',
  678. '<html><head><form>' .
  679. '<label>Stuff' .
  680. '<input type="text" name="a" value="A">' .
  681. '</label>' .
  682. '</form></head></html>');
  683. $page = $this->parse($response);
  684. $this->assertEqual($page->getField(new SimpleByName('a')), 'A');
  685. $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
  686. $this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'aaa'));
  687. $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'aaa');
  688. }
  689. function testGettingTextFieldByEnclosingLabelWithConflictingOtherFields() {
  690. $response = new MockSimpleHttpResponse();
  691. $response->setReturnValue('getContent',
  692. '<html><head><form>' .
  693. '<label>Stuff' .
  694. '<input type="text" name="a" value="A">' .
  695. '</label>' .
  696. '<input type="text" name="b" value="B">' .
  697. '</form></head></html>');
  698. $page = $this->parse($response);
  699. $this->assertEqual($page->getField(new SimpleByName('a')), 'A');
  700. $this->assertEqual($page->getField(new SimpleByName('b')), 'B');
  701. $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
  702. }
  703. function testSettingTextFieldByExternalLabel() {
  704. $response = new MockSimpleHttpResponse();
  705. $response->setReturnValue('getContent',
  706. '<html><head><form>' .
  707. '<label for="aaa">Stuff</label>' .
  708. '<input id="aaa" type="text" name="a" value="A">' .
  709. '</form></head></html>');
  710. $page = $this->parse($response);
  711. $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
  712. $this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'aaa'));
  713. $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'aaa');
  714. }
  715. function testReadingTextArea() {
  716. $response = new MockSimpleHttpResponse();
  717. $response->setReturnValue('getContent',
  718. '<html><head><form>' .
  719. '<textarea name="a">aaa</textarea>' .
  720. '<input type="submit">' .
  721. '</form></head></html>');
  722. $page = $this->parse($response);
  723. $this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
  724. }
  725. function testSettingTextArea() {
  726. $response = new MockSimpleHttpResponse();
  727. $response->setReturnValue('getContent',
  728. '<html><head><form>' .
  729. '<textarea name="a">aaa</textarea>' .
  730. '<input type="submit">' .
  731. '</form></head></html>');
  732. $page = $this->parse($response);
  733. $this->assertTrue($page->setField(new SimpleByName('a'), 'AAA'));
  734. $this->assertEqual($page->getField(new SimpleByName('a')), 'AAA');
  735. }
  736. function testSettingSelectionField() {
  737. $response = new MockSimpleHttpResponse();
  738. $response->setReturnValue('getContent',
  739. '<html><head><form>' .
  740. '<select name="a">' .
  741. '<option>aaa</option>' .
  742. '<option selected>bbb</option>' .
  743. '</select>' .
  744. '<input type="submit">' .
  745. '</form></head></html>');
  746. $page = $this->parse($response);
  747. $this->assertEqual($page->getField(new SimpleByName('a')), 'bbb');
  748. $this->assertFalse($page->setField(new SimpleByName('a'), 'ccc'));
  749. $this->assertTrue($page->setField(new SimpleByName('a'), 'aaa'));
  750. $this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
  751. }
  752. function testSettingSelectionFieldByEnclosingLabel() {
  753. $response = new MockSimpleHttpResponse();
  754. $response->setReturnValue('getContent',
  755. '<html><head><form>' .
  756. '<label>Stuff' .
  757. '<select name="a"><option selected>A</option><option>B</option></select>' .
  758. '</label>' .
  759. '</form></head></html>');
  760. $page = $this->parse($response);
  761. $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
  762. $this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'B'));
  763. $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'B');
  764. }
  765. function testSettingRadioButtonByEnclosingLabel() {
  766. $response = new MockSimpleHttpResponse();
  767. $response->setReturnValue('getContent',
  768. '<html><head><form>' .
  769. '<label>A<input type="radio" name="r" value="a" checked></label>' .
  770. '<label>B<input type="radio" name="r" value="b"></label>' .
  771. '</form></head></html>');
  772. $page = $this->parse($response);
  773. $this->assertEqual($page->getField(new SimpleByLabel('A')), 'a');
  774. $this->assertTrue($page->setField(new SimpleBylabel('B'), 'b'));
  775. $this->assertEqual($page->getField(new SimpleByLabel('B')), 'b');
  776. }
  777. }
  778. ?>