| Index: tools/telemetry/telemetry/page/csv_page_measurement_results.py
 | 
| diff --git a/tools/telemetry/telemetry/page/csv_page_measurement_results.py b/tools/telemetry/telemetry/page/csv_page_measurement_results.py
 | 
| index 0fafbbbcba50a88d36694ddc316d727b5579732b..b57a143a647718b093975053a4973c17088e1100 100644
 | 
| --- a/tools/telemetry/telemetry/page/csv_page_measurement_results.py
 | 
| +++ b/tools/telemetry/telemetry/page/csv_page_measurement_results.py
 | 
| @@ -4,6 +4,7 @@
 | 
|  import csv
 | 
|  
 | 
|  from telemetry.page import page_measurement_results
 | 
| +from telemetry.value import merge_values
 | 
|  
 | 
|  class CsvPageMeasurementResults(
 | 
|      page_measurement_results.PageMeasurementResults):
 | 
| @@ -16,9 +17,10 @@ class CsvPageMeasurementResults(
 | 
|      self._output_after_every_page = output_after_every_page
 | 
|  
 | 
|    def DidMeasurePage(self):
 | 
| -    assert self.values_for_current_page, 'Failed to call WillMeasurePage'
 | 
| +    assert self.page_specific_values_for_current_page
 | 
|  
 | 
| -    if (not self.values_for_current_page.values or
 | 
| +    values = self.page_specific_values_for_current_page
 | 
| +    if (not values or
 | 
|          not self._output_after_every_page):
 | 
|        # Do not output if no results were added on this page or if output flag
 | 
|        # is not set.
 | 
| @@ -30,25 +32,35 @@ class CsvPageMeasurementResults(
 | 
|      else:
 | 
|        self._ValidateOutputNamesForCurrentPage()
 | 
|  
 | 
| -    self._OutputValuesForPage(self.values_for_current_page)
 | 
| +    self._OutputValuesForPage(values[0].page, values)
 | 
|  
 | 
|      super(CsvPageMeasurementResults, self).DidMeasurePage()
 | 
|  
 | 
|    def PrintSummary(self):
 | 
| -    if not self._output_after_every_page:
 | 
| -      self._OutputHeader()
 | 
| -      for page_values in self.page_results:
 | 
| -        self._OutputValuesForPage(page_values)
 | 
| +    if self._output_after_every_page:
 | 
| +      super(CsvPageMeasurementResults, self).PrintSummary()
 | 
| +      return
 | 
| +
 | 
| +    self._OutputHeader()
 | 
| +
 | 
| +    values = merge_values.MergeLikeValuesFromSamePage(
 | 
| +        self.all_page_specific_values)
 | 
| +    value_groups_by_page = merge_values.GroupStably(
 | 
| +        values,
 | 
| +        lambda value: value.page.url)
 | 
| +    for values_for_page in value_groups_by_page:
 | 
| +      self._OutputValuesForPage(values_for_page[0].page,
 | 
| +                                values_for_page)
 | 
|  
 | 
|      super(CsvPageMeasurementResults, self).PrintSummary()
 | 
|  
 | 
|    def _ValidateOutputNamesForCurrentPage(self):
 | 
|      assert self._did_output_header
 | 
| -    current_page_measurement_names = \
 | 
| -        set(self.values_for_current_page.measurement_names)
 | 
| +    current_page_value_names = set([
 | 
| +      value.name for value in self.page_specific_values_for_current_page])
 | 
|      header_names_written_to_writer = \
 | 
|          set(self._header_names_written_to_writer)
 | 
| -    if header_names_written_to_writer == current_page_measurement_names:
 | 
| +    if header_names_written_to_writer == current_page_value_names:
 | 
|        return
 | 
|      assert False, """To use CsvPageMeasurementResults, you must add the same
 | 
|  result names for every page. In this case, first page output:
 | 
| @@ -61,31 +73,34 @@ output:
 | 
|  Change your test to produce the same thing each time, or modify
 | 
|  PageMeasurement.results_are_the_same_on_every_page to return False.
 | 
|  """ % (repr(header_names_written_to_writer),
 | 
| -       repr(current_page_measurement_names))
 | 
| +       repr(current_page_value_names))
 | 
|  
 | 
|    def _OutputHeader(self):
 | 
|      assert not self._did_output_header
 | 
| -    all_measurement_names = list(
 | 
| -      self.all_measurements_that_have_been_seen.keys())
 | 
| -    all_measurement_names.sort()
 | 
| +    all_value_names = list(
 | 
| +      self.all_value_names_that_have_been_seen)
 | 
| +    all_value_names.sort()
 | 
|      self._did_output_header = True
 | 
| -    self._header_names_written_to_writer = list(all_measurement_names)
 | 
| +    self._header_names_written_to_writer = list(all_value_names)
 | 
|  
 | 
|      row = ['page_name']
 | 
| -    for measurement_name in all_measurement_names:
 | 
| -      measurement_data = \
 | 
| -          self.all_measurements_that_have_been_seen[measurement_name]
 | 
| -      row.append('%s (%s)' % (measurement_name, measurement_data['units']))
 | 
| +    for value_name in all_value_names:
 | 
| +      units = self.GetUnitsForValueName(value_name)
 | 
| +      row.append('%s (%s)' % (value_name, units))
 | 
|      self._results_writer.writerow(row)
 | 
|      self._output_stream.flush()
 | 
|  
 | 
| -  def _OutputValuesForPage(self, page_values):
 | 
| -    row = [page_values.page.display_name]
 | 
| -    for measurement_name in self._header_names_written_to_writer:
 | 
| -      value = page_values.FindValueByMeasurementName(measurement_name)
 | 
| -      if value:
 | 
| -        row.append('%s' % value.output_value)
 | 
| +  def _OutputValuesForPage(self, page, page_values):
 | 
| +    row = [page.display_name]
 | 
| +    values_by_value_name = {}
 | 
| +    for value in page_values:
 | 
| +      values_by_value_name[value.name] = value
 | 
| +
 | 
| +    for value_name in self._header_names_written_to_writer:
 | 
| +      value = values_by_value_name.get(value_name, None)
 | 
| +      if value and value.GetRepresentativeNumber():
 | 
| +        row.append('%s' % value.GetRepresentativeNumber())
 | 
|        else:
 | 
|          row.append('-')
 | 
|      self._results_writer.writerow(row)
 | 
| -    self._output_stream.flush()
 | 
| +    self._output_stream.flush()
 | 
| 
 |