query_handler_spec.rb 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. require 'spec_helper'
  2. RSpec.describe 'Query handler tests' do
  3. describe 'Text selectors' do
  4. describe 'in Page' do
  5. it 'should query existing element' do
  6. page.content = '<section>test</section>'
  7. expect(page.query_selector('text/test').evaluate('el => el.tagName')).to eq('SECTION')
  8. expect(page.query_selector_all('text/test').size).to eq(1)
  9. end
  10. it 'should return empty array for non-existing element' do
  11. page.content = '<section>xxx</section>'
  12. expect(page.query_selector('text/test')).to be_nil
  13. expect(page.query_selector_all('text/test')).to be_empty
  14. end
  15. it 'should return first element' do
  16. page.content ='<div id="1">a</div><div>a</div>'
  17. element = page.query_selector('text/a')
  18. expect(element['id'].json_value).to eq('1')
  19. end
  20. it 'should return multiple elements' do
  21. page.content ='<div>a</div><div>a</div>'
  22. elements = page.query_selector_all('text/a')
  23. expect(elements.size).to eq(2)
  24. end
  25. it 'should pierce shadow DOM' do
  26. js = <<~JAVASCRIPT
  27. () => {
  28. const div = document.createElement('div');
  29. const shadow = div.attachShadow({mode: 'open'});
  30. const diva = document.createElement('div');
  31. shadow.append(diva);
  32. const divb = document.createElement('div');
  33. shadow.append(divb);
  34. diva.innerHTML = 'a';
  35. divb.innerHTML = 'b';
  36. document.body.append(div);
  37. }
  38. JAVASCRIPT
  39. page.evaluate(js)
  40. element = page.query_selector('text/a')
  41. expect(element.evaluate('el => el.textContent')).to eq('a')
  42. end
  43. it 'should query deeply nested text' do
  44. page.content = '<div><div>a</div><div>b</div></div>'
  45. element = page.query_selector('text/a')
  46. expect(element.evaluate('el => el.textContent')).to eq('a')
  47. end
  48. it 'should query inputs' do
  49. page.content = '<input type="text" value="a" /><div>a</div>'
  50. element = page.query_selector('text/a')
  51. expect(element.evaluate('el => el.tagName')).to eq('INPUT')
  52. end
  53. it 'should not query radio' do
  54. page.content = '<input type="radio" value="a" />'
  55. expect(page.query_selector('text/a')).to be_nil
  56. end
  57. it 'should query text spanning multiple elements' do
  58. page.content = '<div><span>a</span> <span>b</span><div>'
  59. element = page.query_selector('text/a b')
  60. expect(element.evaluate('el => el.tagName')).to eq('DIV')
  61. end
  62. end
  63. describe 'in ElementHandles' do
  64. it 'should query existing element' do
  65. page.content = '<div class="a"><span>a</span></div>'
  66. element_handle = page.query_selector('div')
  67. expect(element_handle.query_selector('text/a').evaluate('el => el.outerHTML')).to eq('<span>a</span>')
  68. expect(element_handle.query_selector_all('text/a').size).to eq(1)
  69. end
  70. it 'should return null for non-existing element' do
  71. page.content = '<div class="a"></div>'
  72. element_handle = page.query_selector('div')
  73. expect(element_handle.query_selector('text/a')).to be_nil
  74. expect(element_handle.query_selector_all('text/a')).to be_empty
  75. end
  76. end
  77. end
  78. describe 'XPath selectors' do
  79. describe 'in Page' do
  80. it 'should query existing element' do
  81. page.content = '<section>test</section>'
  82. el = page.query_selector('xpath/html/body/section')
  83. expect(el).to be_a(Puppeteer::ElementHandle)
  84. expect(el.evaluate('el => el.textContent')).to eq('test')
  85. elements = page.query_selector_all('xpath/html/body/section')
  86. expect(elements.size).to eq(1)
  87. el = elements.first
  88. expect(el).to be_a(Puppeteer::ElementHandle)
  89. expect(el.evaluate('el => el.textContent')).to eq('test')
  90. end
  91. it 'should return empty array for non-existing element' do
  92. el = page.query_selector('xpath/html/body/non-existing-element')
  93. expect(el).to be_nil
  94. elements = page.query_selector_all('xpath/html/body/non-existing-element')
  95. expect(elements).to be_empty
  96. end
  97. it 'should return first element' do
  98. page.content = '<div>a</div><div>b</div>'
  99. el = page.query_selector('xpath/html/body/div')
  100. expect(el.evaluate('el => el.textContent')).to eq('a')
  101. end
  102. it 'should return multiple elements' do
  103. page.content = '<div>a</div><div>b</div>'
  104. elements = page.query_selector_all('xpath/html/body/div')
  105. expect(elements.size).to eq(2)
  106. expect(elements.first.evaluate('el => el.textContent')).to eq('a')
  107. expect(elements.last.evaluate('el => el.textContent')).to eq('b')
  108. end
  109. end
  110. describe 'in ElementHandles' do
  111. it 'should query existing element' do
  112. page.content = '<span>outer</span><div class="a">a<span>inner</span></div>'
  113. div = page.query_selector('div')
  114. el = div.query_selector('xpath/span')
  115. expect(el).to be_a(Puppeteer::ElementHandle)
  116. expect(el.evaluate('el => el.textContent')).to eq('inner')
  117. elements = div.query_selector_all('xpath/span')
  118. expect(elements.size).to eq(1)
  119. el = elements.first
  120. expect(el).to be_a(Puppeteer::ElementHandle)
  121. expect(el.evaluate('el => el.textContent')).to eq('inner')
  122. end
  123. it 'should return null for non-existing element' do
  124. page.content = '<div class="a">a</div>'
  125. div = page.query_selector('div')
  126. el = div.query_selector('xpath/div')
  127. expect(el).to be_nil
  128. elements = div.query_selector_all('xpath/html/body/div')
  129. expect(elements).to be_empty
  130. end
  131. end
  132. end
  133. end