Пример #1
0
 def _submit_form(self):
     log.info("Submitting dates.")
     with IFrameSwitch(self._driver, "childFrame"):
         with IFrameSwitch(self._driver, "frame3"):
             self._driver.wait().until(
                 EC.element_to_be_clickable(
                     (By.XPATH, self.done_button_xpath)))
             self._driver.click(self.done_button_xpath, xpath=True)
Пример #2
0
 def get_install_date(self):
     """
     Install date is the earliest date we can request -
     located in a hidden input element on the page.
     """
     with IFrameSwitch(self._driver, "childFrame"):
         with IFrameSwitch(self._driver, "frame3"):
             log.info("Finding inverter install date.")
             return self._driver.find_or_raise(
                 self.install_date_selector).get_attribute("value")
Пример #3
0
 def click_ac_power_button(self):
     """
     This switches data to kW format.
     """
     with IFrameSwitch(self._driver, "childFrame"):
         with IFrameSwitch(self._driver, "frame3"):
             log.info("Waiting to see AC Power Button.")
             self._driver.wait().until(
                 EC.element_to_be_clickable((By.ID, self.ac_power_id)))
             log.info("Clicking AC Power button.")
             self._driver.find_element_by_id(self.ac_power_id).click()
             self._driver.sleep(1)
Пример #4
0
 def _click_range_button(self):
     """
     This opens a form with two datepickers.
     """
     with IFrameSwitch(self._driver, "childFrame"):
         with IFrameSwitch(self._driver, "frame3"):
             self._driver.wait().until(
                 EC.element_to_be_clickable(
                     (By.CSS_SELECTOR, self.range_button_selector)))
             log.info("Clicking on Range button.")
             self._driver.click(self.range_button_selector)
             self._driver.sleep(1)
Пример #5
0
    def _enter_date(self, date_obj: datetime, date_input_selector):
        with IFrameSwitch(self._driver, "childFrame"):
            with IFrameSwitch(self._driver, "frame3"):
                self._driver.wait().until(
                    EC.presence_of_element_located(
                        (By.CSS_SELECTOR, date_input_selector)))
                self._driver.clear(date_input_selector)
                date_string = self.date_to_string(date_obj)
                log.info("Entering date {}".format(date_string))
                self._driver.fill(date_input_selector, date_string)

                # Click outside of the date picker, helps make "Done" button selectable
                self._driver.click(self.title_dialog_selector)
                self._driver.sleep(2)
Пример #6
0
    def get_bill_details(self, bill_row: BillSummaryRow):
        """Click on the 'details' link for a given bill summary, and scrape the resulting page"""
        with IFrameSwitch(self.driver, "mainFrame"):
            # We open the page in a new window by shift-clicking.
            actions = ActionChains(self.driver)
            actions.move_to_element(bill_row.detail_link)
            actions.key_down(Keys.SHIFT)
            actions.click(bill_row.detail_link)
            actions.key_up(Keys.SHIFT)
            actions.perform()

        self.driver.wait().until(window_count_equals(2))
        other_window = self.driver.window_handles[1]
        detail_raw = {}
        with WindowSwitch(self.driver, other_window, close=True):
            WebDriverWait(self.driver, 20).until(
                EC.presence_of_element_located((By.XPATH, "//table")))
            table = self.driver.find_element_by_tag_name("table")
            for row in table.find_elements_by_tag_name("tr"):
                cells = row.find_elements_by_tag_name("td")
                if len(cells) >= 2:
                    row_label = cells[0].text.strip()
                    detail_raw[row_label] = cells[1].text.strip()

        return BillDetail(
            account=str(detail_raw["Account"]),
            rate=str(detail_raw["Rate"]),
            bill_start=parse_date(detail_raw["Bill Start"]).date(),
            bill_stop=parse_date(detail_raw["Bill Stop"]).date(),
            total_kwh=self.parse_float(detail_raw["Total kWh"]),
            on_peak_kw=self.parse_float(detail_raw["On Peak KW"]),
            cost=self.parse_cost(detail_raw["Total Bill"]),
        )
Пример #7
0
 def func_wrapper(self, *args, **kwargs):
     iframe_selector = self.get_iframe_selector()
     if iframe_selector:
         # Switches to iframe only if exists
         with IFrameSwitch(self._driver, self.get_iframe_selector()):
             return func(self, *args, **kwargs)
     else:
         return func(self, *args, **kwargs)
Пример #8
0
    def select_inverter_from_both_dropdowns(self, inverter_id: str):
        """
        SolrenView has two dropdowns to compare inverters. Since we're
        scraping one inverter at a time, we're selecting the same inverter
        from both dropdowns - this will also halve the amount of data we're
        requesting at a time.
        """
        with IFrameSwitch(self._driver, "childFrame"):
            with IFrameSwitch(self._driver, "frame3"):
                log.info("Selecting inverter from LHS dropdown.")
                self._select_individual_inverter(
                    self.dropdown_button_one_selector, self.lhs_li_xpath,
                    inverter_id)

                log.info("Selecting same inverter from RHS dropdown.")
                self._select_individual_inverter(
                    self.dropdown_button_two_selector, self.rhs_li_xpath,
                    inverter_id)
Пример #9
0
    def get_meters(self) -> List[MeterInfo]:
        """Scrape the meter data from this page into a list of MeterInfo objects"""
        results = []
        with IFrameSwitch(self.driver, "mainFrame"):
            table = self.driver.find_element(*self.ProfileTableLocator)
            current_meter = None
            current_stop_date = None

            for row in table.find_elements_by_tag_name("tr"):
                # This table has two kinds of rows: "primary" rows, which describe a meter and its first channel;
                # and supplementary "channel" rows, which describe additional channels for a given meter. The
                # primary row will appear first, followed by a channel row for each channel beyond the first.
                # Therefore, we keep track of the "current" meter, so that when we come across a channel row we
                # known which meter to associate it with.

                cells = row.find_elements_by_tag_name("td")
                if len(cells) >= 9:
                    # Each meter channel reports the dates for which data is available (start and end date). However,
                    # in all observed cases the end date is specified once, on the primary row for the meter (opposed
                    # to the start date, which appears for each channel). However, in case its possible for a channel
                    # to report a different stop date, we still check for one, even if we are sitting on a channel row.
                    if len(cells) == 10:
                        current_stop_date = parse_date(
                            cells[9].text.strip()).date()

                    meter_name = cells[0].text.strip()
                    if meter_name:
                        # This indicates we have hit a new "primary" row, and thus need to emit a record for the
                        # previous active meter, if there is one.
                        if current_meter:
                            results.append(current_meter)

                        current_meter = MeterInfo(
                            name=cells[0].text.strip(),
                            account=cells[1].text.strip(),
                            meter_id=cells[2].text.strip(),
                            address=cells[3].text.strip(),
                            meter_number=cells[4].text.strip(),
                            iph=cells[5].text.strip(),
                            channels=[],
                        )

                    if current_meter:
                        current_meter.channels.append(
                            ChannelInfo(
                                id=cells[6].text.strip(),
                                units=cells[7].text.strip(),
                                data_start=parse_date(
                                    cells[8].text.strip()).date(),
                                data_end=current_stop_date,
                            ))

            if current_meter:
                results.append(current_meter)

        return results
Пример #10
0
    def set_date_range(self, start: date, end: date):
        date_format = "%m/%d/%Y"
        with IFrameSwitch(self.driver, "mainFrame"):
            start_elem = self.driver.find_element(*self.StartDateLocator)
            start_elem.clear()
            start_elem.send_keys(start.strftime(date_format))

            end_elem = self.driver.find_element(*self.StopDateLocator)
            end_elem.clear()
            end_elem.send_keys(end.strftime(date_format))
Пример #11
0
    def select_account(self, account_id):
        with IFrameSwitch(self.driver, "mainFrame"):
            selector = Select(
                self.driver.find_element(*self.MeterSelectLocator))

            try:
                selector.select_by_value(account_id)
            except NoSuchElementException:
                raise saltriver_errors.MeterNotFoundError.for_account(
                    account_id)
Пример #12
0
    def _export_data(self) -> str:
        log.info("Exporting data.")
        with IFrameSwitch(self._driver, "childFrame"):
            with IFrameSwitch(self._driver, "frame3"):
                self._driver.wait().until(
                    EC.element_to_be_clickable(
                        (By.XPATH, self.export_data_xpath)))
                self._driver.sleep(2)

                export_button = self._driver.find_element_by_xpath(
                    self.export_data_xpath)
                self._driver.execute_script("arguments[0].click();",
                                            export_button)

                # Wait for csv to download
                download_dir = self._driver.download_dir
                filename = self._driver.wait(60).until(
                    file_exists_in_dir(download_dir, r".*\.csv$"))
                file_path = os.path.join(download_dir, filename)
                return file_path
Пример #13
0
 def get_bill_summaries(self):
     results = []
     with IFrameSwitch(self.driver, "mainFrame"):
         table = self.driver.find_element(*self.BillTableLocator)
         for row in table.find_elements_by_tag_name("tr"):
             cells = row.find_elements_by_tag_name("td")
             if len(cells) == 10 and cells[0].text.strip() != "Total":
                 results.append(
                     BillSummaryRow(
                         detail_link=cells[0].find_element_by_tag_name("a"),
                         stop_date=parse_date(cells[1].text.strip()).date(),
                         rate=cells[2].text.strip(),
                         max_kw=self.parse_float(cells[3].text.strip()),
                         total_kwh=self.parse_float(cells[4].text.strip()),
                         cost=self.parse_cost(cells[9].text.strip()),
                     ))
     return results
Пример #14
0
 def goto_bill_history(self):
     with IFrameSwitch(self.driver, "mainFrame"):
         self.driver.find_element(*self.BillsByAccountLink).click()
Пример #15
0
 def download_interval_data(self):
     with IFrameSwitch(self.driver, "mainFrame"):
         log.info("clicking submit")
         self.driver.find_element(*self.SubmitSelector).click()
Пример #16
0
 def select_meter_by_id(self, meter_id: str):
     log.info("select meter by id")
     with IFrameSwitch(self.driver, "mainFrame"):
         selector = Select(
             self.driver.find_element(*self.MeterSelectLocator))
         selector.select_by_value(meter_id)
Пример #17
0
 def basic_configuration(self):
     log.info("basic_configuration")
     with IFrameSwitch(self.driver, "mainFrame"):
         self.driver.find_element(*self.FifteenMinuteOptionLocator).click()
         self.driver.find_element(*self.DemandDatatypeLocator).click()
Пример #18
0
 def generate_report(self):
     with IFrameSwitch(self.driver, "mainFrame"):
         self.driver.find_element(*self.NextButtonLocator).click()
Пример #19
0
 def select_longest_report(self):
     with IFrameSwitch(self.driver, "mainFrame"):
         selectors = self.driver.find_elements(*self.TimeButtonSelector)
         longest = max(selectors,
                       key=lambda s: int(s.get_attribute("value")))
         longest.click()
Пример #20
0
 def wait_until_ready(self):
     with IFrameSwitch(self._driver, "childFrame"):
         log.info("Waiting to see the site analytics tab.")
         self._driver.wait().until(
             EC.presence_of_element_located(
                 (By.XPATH, self.site_analytics_xpath)))
Пример #21
0
 def goto_meter_profiles(self):
     with IFrameSwitch(self.driver, "mainFrame"):
         self.driver.find_element(*self.MeterProfilesLink).click()
Пример #22
0
 def navigate_to_site_analytics(self):
     with IFrameSwitch(self._driver, "childFrame"):
         log.info("Clicking on the site analytics tab.")
         self._driver.click(self.site_analytics_xpath, xpath=True)
Пример #23
0
 def wait_until_ready(self):
     with IFrameSwitch(self._driver, "childFrame"):
         # Page blocked by a loading indicator - wait for this to disappear
         self._driver.wait().until(
             EC.invisibility_of_element_located(
                 (By.XPATH, self.block_ui_xpath)))
Пример #24
0
 def goto_interval_download(self):
     log.info("click interval download")
     with IFrameSwitch(self.driver, "mainFrame"):
         self.driver.find_element(*self.IntervalDownloadLink).click()
Пример #25
0
 def goto_reports(self):
     with IFrameSwitch(self.driver, "banner"):
         self.driver.find_element(*self.ReportPageLink).click()