Repository: pandas-dev/pandas

Issue:
TST: random html testing issues
I have seen these errors spuriously: https://travis-ci.org/jreback/pandas/jobs/79852164

but they go away when re-run...any ideas?

```
======================================================================
FAIL: test_to_html_truncate (pandas.tests.test_format.TestDataFrameFormatting)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/jreback/pandas/pandas/tests/test_format.py", line 999, in test_to_html_truncate
    self.assertEqual(result, expected)
AssertionError: u'<div style="max-width:1500px;overflow:auto;">\n<table border="1" class="datafr [truncated]... != u'<div>\n<table border="1" class="dataframe">\n  <thead>\n    <tr style="text-al [truncated]...
Diff is 1759 characters long. Set self.maxDiff to None to see it.
======================================================================
FAIL: test_to_html_truncate_multi_index (pandas.tests.test_format.TestDataFrameFormatting)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/jreback/pandas/pandas/tests/test_format.py", line 1115, in test_to_html_truncate_multi_index
    self.assertEqual(result, expected)
AssertionError: u'<div style="max-width:1500px;overflow:auto;">\n<table border="1" class="datafr [truncated]... != u'<div>\n<table border="1" class="dataframe">\n  <thead>\n    <tr>\n      <th></ [truncated]...
Diff is 2107 characters long. Set self.maxDiff to None to see it.
======================================================================
FAIL: test_to_html_truncate_multi_index_sparse_off (pandas.tests.test_format.TestDataFrameFormatting)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/jreback/pandas/pandas/tests/test_format.py", line 1225, in test_to_html_truncate_multi_index_sparse_off
    self.assertEqual(result, expected)
AssertionError: u'<div style="max-width:1500px;overflow:auto;">\n<table border="1" class="datafr [truncated]... != u'<div>\n<table border="1" class="dataframe">\n  <thead>\n    <tr>\n      <th></ [truncated]...
Diff is 1877 characters long. Set self.maxDiff to None to see it.
----------------------------------------------------------------------
Ran 9032 tests in 947.494s
```



Discussion:

Resolving patch:
diff --git a/pandas/io/formats/html.py b/pandas/io/formats/html.py
--- a/pandas/io/formats/html.py
+++ b/pandas/io/formats/html.py
@@ -241,7 +241,7 @@ def _write_col_header(self, indent):
                 # GH3547
                 sentinel = com.sentinel_factory()
             else:
-                sentinel = None
+                sentinel = False
             levels = self.columns.format(sparsify=sentinel, adjoin=False,
                                          names=False)
             level_lengths = get_level_lengths(levels, sentinel)
@@ -440,9 +440,6 @@ def _write_hierarchical_rows(self, fmt_values, indent):
         truncate_v = self.fmt.truncate_v
         frame = self.fmt.tr_frame
         nrows = len(frame)
-        # TODO: after gh-22887 fixed, refactor to use class property
-        # in place of row_levels
-        row_levels = self.frame.index.nlevels
 
         idx_values = frame.index.format(sparsify=False, adjoin=False,
                                         names=False)
@@ -520,18 +517,24 @@ def _write_hierarchical_rows(self, fmt_values, indent):
 
                 row.extend(fmt_values[j][i] for j in range(self.ncols))
                 if truncate_h:
-                    row.insert(row_levels - sparse_offset +
+                    row.insert(self.row_levels - sparse_offset +
                                self.fmt.tr_col_num, '...')
                 self.write_tr(row, indent, self.indent_delta, tags=tags,
                               nindex_levels=len(levels) - sparse_offset)
         else:
+            row = []
             for i in range(len(frame)):
+                if truncate_v and i == (self.fmt.tr_row_num):
+                    str_sep_row = ['...'] * len(row)
+                    self.write_tr(str_sep_row, indent, self.indent_delta,
+                                  tags=None, nindex_levels=self.row_levels)
+
                 idx_values = list(zip(*frame.index.format(
                     sparsify=False, adjoin=False, names=False)))
                 row = []
                 row.extend(idx_values[i])
                 row.extend(fmt_values[j][i] for j in range(self.ncols))
                 if truncate_h:
-                    row.insert(row_levels + self.fmt.tr_col_num, '...')
+                    row.insert(self.row_levels + self.fmt.tr_col_num, '...')
                 self.write_tr(row, indent, self.indent_delta, tags=None,
                               nindex_levels=frame.index.nlevels)


Test patch:
diff --git a/pandas/tests/io/formats/data/html/truncate_multi_index_sparse_off.html b/pandas/tests/io/formats/data/html/truncate_multi_index_sparse_off.html
--- a/pandas/tests/io/formats/data/html/truncate_multi_index_sparse_off.html
+++ b/pandas/tests/io/formats/data/html/truncate_multi_index_sparse_off.html
@@ -57,6 +57,17 @@
       <td>NaN</td>
       <td>NaN</td>
     </tr>
+    <tr>
+      <th>...</th>
+      <th>...</th>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+      <td>...</td>
+    </tr>
     <tr>
       <th>foo</th>
       <th>two</th>
diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py
--- a/pandas/tests/io/formats/test_to_html.py
+++ b/pandas/tests/io/formats/test_to_html.py
@@ -223,7 +223,6 @@ def test_to_html_truncate_multi_index(self, datapath):
         expected = expected_html(datapath, 'truncate_multi_index')
         assert result == expected
 
-    @pytest.mark.xfail(reason='GH22887 TypeError')
     def test_to_html_truncate_multi_index_sparse_off(self, datapath):
         arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
                   ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]