How to click a “select option” and then evaluate loaded content with casperjs

后端 未结 9 1416
长情又很酷
长情又很酷 2021-01-02 01:46

I\'m trying to crawl the sizes for this product:

Link to product

The problem: The sizes are loaded after the color of the product is selected.

In th

相关标签:
9条回答
  • 2021-01-02 01:54

    The recommended jQuery solution doesn't actually work for me.

    casper.evaluate(function() {
        $('#select_element_selector').val('value').change();
    });
    

    While, the capture() command shows the select option as selected visually, it doesn't actually trigger the event. Try using this with the waitForText() command for example; the program will timeout.

    casper
      .start('http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=DEC_00_SF1_DP1&prodType=table')
      .waitForText('Add/Remove Geographies', function () {
        casper.click('#addRemoveGeo_btn');
      })
      .waitForText('Select a geographic type:', function () {
        casper.evaluate(function () {
          $('#summaryLevel').val('050').change();
        });
      })
      .waitForText('Select a state:', function () {
        casper.capture('test.png');
      })
      .run();
    

    What did work for me, was the code provided below (thanks @ArtjomB). How to fill a select element which is not embedded in a form with CasperJS?

    casper.selectOptionByValue = function(selector, valueToMatch){
        this.evaluate(function(selector, valueToMatch){
            var select = document.querySelector(selector),
                found = false;
            Array.prototype.forEach.call(select.children, function(opt, i){
                if (!found && opt.value.indexOf(valueToMatch) !== -1) {
                    select.selectedIndex = i;
                    found = true;
                }
            });
            // dispatch change event in case there is some kind of validation
            var evt = document.createEvent("UIEvents"); // or "HTMLEvents"
            evt.initUIEvent("change", true, true);
            select.dispatchEvent(evt);
        }, selector, valueToMatch);
    };
    
    casper.selectOptionByValue('#summaryLevel', '050');
    

    Although, I think CasperJS should provide native support to select options from a drop-down when they aren't apart of a form (http://docs.casperjs.org/en/latest/modules/index.html). Selenium offers the select and addSelection commands (https://seleniumhq.github.io/selenium/docs/api/javascript/index.html). I've also filed a pending issue ticket on the CasperJS GitHub page to implement this natively (https://github.com/n1k0/casperjs/issues/1390).

    0 讨论(0)
  • 2021-01-02 01:54

    vanilla javascript solution (triggering onchange method):

    casper.evaluate(function() {
        var select_element = document.getElementById('select_element_selector');
        select_element.value = 'value';
        select_element.onchange();
    });
    
    0 讨论(0)
  • 2021-01-02 01:59

    tejesh95's solution worked for me with a few minor changes, #1 I couldn't get findElementById to work so switched it to 'document.querySelector('#selectorId)' . I also had to change 'onchange' to 'onclick'. Here's the code within the casperjs test harness:

    casper.then(function() {
      this.evaluate(function() {
      var select_element = document.querySelector('#selectorId')
      select_element.value = 'stringValue'
      select_element.onclick
    })
    

    })

    Follow on note: Your mileage may vary on the above, I found inconsistent results elsewhere, the text value would update, but the underlying control wouldn't fire. Frustrating!

    0 讨论(0)
  • 2021-01-02 02:05

    this is simple code to enter credit card details in casper js

    casper.evaluate(function(CC,security_code) {

          document.querySelector('input#receipt_creditcard_number').value = CC;
          document.querySelector('select#receipt_creditcard_month').selectedIndex = 10;
          document.querySelector('select#receipt_creditcard_year').selectedIndex = 10;
          document.querySelector('input#receipt_creditcard_verification_value').value = security_code;
          document.querySelector('input#receipt_save_creditcard_in_profile').click();
      }, '4242424242424242','123');
    
    0 讨论(0)
  • 2021-01-02 02:07

    I don't know if you found a solution to your problem, but here is how I would solve it:

    casper.click('#color');
    casper.then(function() {
    casper.waitFor(function check() {
      return this.evaluate(function() {
        return document.querySelector('select.select-category').selectedIndex === 2; 
      });
    }, function then() {
         /* do the rest that you would want to do!*/
       });
    
    }
    
    0 讨论(0)
  • 2021-01-02 02:09

    A slightly hacky way to do this without using jQuery utilising built-in casper methods is:

    // Assumes the select box is on the first item at index 0
    chooseSelectOption = (friendlyName : string, selectLocator : string, optionIndex : number) => {
        casper.test.assertExists(selectLocator, "then select index " + optionIndex + " in the " + friendlyName + " select box");
        casper.click(selectLocator);
        this.goDown(selectLocator, optionIndex);
    };
    
    // recursive funtion to go down various levels
    private goDown = (locator: string, depth : number, currentLevel : number = 0) => {
        if (currentLevel >= depth) { return; }
        casper.sendKeys(locator, casper.page.event.key.Down, { keepFocus: true });
        this.goDown(locator, depth, currentLevel + 1);
    };
    

    This is in TypeScript but you can edit for vanilla JS if you need to. You need to use a recursive function because a normal for loop gets into difficulties with capser's queuing system.

    0 讨论(0)
提交回复
热议问题