1
1
mirror of https://github.com/Kozea/WeasyPrint.git synced 2024-10-04 07:57:52 +03:00
WeasyPrint/tests/layout/test_table.py
2022-06-28 15:59:06 +02:00

2915 lines
84 KiB
Python

"""Tests for layout of tables."""
import pytest
from ..testing_utils import assert_no_logs, capture_logs, render_pages
@assert_no_logs
def test_inline_table():
page, = render_pages('''
<table style="display: inline-table; border-spacing: 10px; margin: 5px">
<tr>
<td><img src=pattern.png style="width: 20px"></td>
<td><img src=pattern.png style="width: 30px"></td>
</tr>
</table>
foo
''')
html, = page.children
body, = html.children
line, = body.children
table_wrapper, text = line.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 15 # 0 + border-spacing
assert td_1.width == 20
assert td_2.position_x == 45 # 15 + 20 + border-spacing
assert td_2.width == 30
assert table.width == 80 # 20 + 30 + 3 * border-spacing
assert table_wrapper.margin_width() == 90 # 80 + 2 * margin
assert text.position_x == 90
@assert_no_logs
def test_implicit_width_table_col_percent():
# See https://github.com/Kozea/WeasyPrint/issues/169
page, = render_pages('''
<table>
<col style="width:25%"></col>
<col></col>
<tr>
<td></td>
<td></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
@assert_no_logs
def test_implicit_width_table_td_percent():
page, = render_pages('''
<table>
<tr>
<td style="width:25%"></td>
<td></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
@assert_no_logs
def test_layout_table_fixed_1():
page, = render_pages('''
<table style="table-layout: fixed; border-spacing: 10px; margin: 5px">
<colgroup>
<col style="width: 20px" />
</colgroup>
<tr>
<td></td>
<td style="width: 40px">a</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 15 # 5 + border-spacing
assert td_1.width == 20
assert td_2.position_x == 45 # 15 + 20 + border-spacing
assert td_2.width == 40
assert table.width == 90 # 20 + 40 + 3 * border-spacing
@assert_no_logs
def test_layout_table_fixed_2():
page, = render_pages('''
<table style="table-layout: fixed; border-spacing: 10px; width: 200px;
margin: 5px">
<tr>
<td style="width: 20px">a</td>
<td style="width: 40px"></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 15 # 5 + border-spacing
assert td_1.width == 75 # 20 + ((200 - 20 - 40 - 3 * border-spacing) / 2)
assert td_2.position_x == 100 # 15 + 75 + border-spacing
assert td_2.width == 95 # 40 + ((200 - 20 - 40 - 3 * border-spacing) / 2)
assert table.width == 200
@assert_no_logs
def test_layout_table_fixed_3():
page, = render_pages('''
<table style="table-layout: fixed; border-spacing: 10px;
width: 110px; margin: 5px">
<tr>
<td style="width: 40px">a</td>
<td>b</td>
</tr>
<tr>
<td style="width: 50px">a</td>
<td style="width: 30px">b</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row_1, row_2 = row_group.children
td_1, td_2 = row_1.children
td_3, td_4 = row_2.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 15 # 0 + border-spacing
assert td_3.position_x == 15
assert td_1.width == 40
assert td_2.width == 40
assert td_2.position_x == 65 # 15 + 40 + border-spacing
assert td_4.position_x == 65
assert td_3.width == 40
assert td_4.width == 40
assert table.width == 110 # 20 + 40 + 3 * border-spacing
@assert_no_logs
def test_layout_table_fixed_4():
page, = render_pages('''
<table style="table-layout: fixed; border-spacing: 0;
width: 100px; margin: 10px">
<colgroup>
<col />
<col style="width: 20px" />
</colgroup>
<tr>
<td></td>
<td style="width: 40px">a</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 10 # 0 + margin-left
assert td_1.position_x == 10
assert td_1.width == 80 # 100 - 20
assert td_2.position_x == 90 # 10 + 80
assert td_2.width == 20
assert table.width == 100
@assert_no_logs
def test_layout_table_fixed_5():
# With border-collapse
page, = render_pages('''
<style>
/* Do not apply: */
colgroup, col, tbody, tr, td { margin: 1000px }
</style>
<table style="table-layout: fixed;
border-collapse: collapse; border: 10px solid;
/* ignored with collapsed borders: */
border-spacing: 10000px; padding: 1000px">
<colgroup>
<col style="width: 30px" />
</colgroup>
<tbody>
<tr>
<td style="padding: 2px"></td>
<td style="width: 34px; padding: 10px; border: 2px solid"></td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 0
assert table.border_left_width == 5 # half of the collapsed 10px border
assert td_1.position_x == 5 # border-spacing is ignored
assert td_1.margin_width() == 30 # as <col>
assert td_1.width == 20 # 30 - 5 (border-left) - 1 (border-right) - 2*2
assert td_2.position_x == 35
assert td_2.width == 34
assert td_2.margin_width() == 60 # 34 + 2*10 + 5 + 1
assert table.width == 90 # 30 + 60
assert table.margin_width() == 100 # 90 + 2*5 (border)
@assert_no_logs
def test_layout_table_auto_1():
page, = render_pages('''
<body style="width: 100px">
<table style="border-spacing: 10px; margin: auto">
<tr>
<td><img src=pattern.png></td>
<td><img src=pattern.png></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table_wrapper.width == 38 # Same as table, see below
assert table_wrapper.margin_left == 31 # 0 + margin-left = (100 - 38) / 2
assert table_wrapper.margin_right == 31
assert table.position_x == 31
assert td_1.position_x == 41 # 31 + spacing
assert td_1.width == 4
assert td_2.position_x == 55 # 31 + 4 + spacing
assert td_2.width == 4
assert table.width == 38 # 3 * spacing + 2 * 4
@assert_no_logs
def test_layout_table_auto_2():
page, = render_pages('''
<body style="width: 50px">
<table style="border-spacing: 1px; margin: 10%">
<tr>
<td style="border: 3px solid black"><img src=pattern.png></td>
<td style="border: 3px solid black">
<img src=pattern.png><img src=pattern.png>
</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 6 # 5 + border-spacing
assert td_1.width == 4
assert td_2.position_x == 17 # 6 + 4 + spacing + 2 * border
assert td_2.width == 8
assert table.width == 27 # 3 * spacing + 4 + 8 + 4 * border
@assert_no_logs
def test_layout_table_auto_3():
page, = render_pages('''
<table style="border-spacing: 1px; margin: 5px; font-size: 0">
<tr>
<td></td>
<td><img src=pattern.png><img src=pattern.png></td>
</tr>
<tr>
<td>
<img src=pattern.png>
<img src=pattern.png>
<img src=pattern.png>
</td>
<td><img src=pattern.png></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row1, row2 = row_group.children
td_11, td_12 = row1.children
td_21, td_22 = row2.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_11.position_x == td_21.position_x == 6 # 5 + spacing
assert td_11.width == td_21.width == 12
assert td_12.position_x == td_22.position_x == 19 # 6 + 12 + spacing
assert td_12.width == td_22.width == 8
assert table.width == 23 # 3 * spacing + 12 + 8
@assert_no_logs
def test_layout_table_auto_4():
page, = render_pages('''
<table style="border-spacing: 1px; margin: 5px">
<tr>
<td style="border: 1px solid black"><img src=pattern.png></td>
<td style="border: 2px solid black; padding: 1px">
<img src=pattern.png>
</td>
</tr>
<tr>
<td style="border: 5px solid black"><img src=pattern.png></td>
<td><img src=pattern.png></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row1, row2 = row_group.children
td_11, td_12 = row1.children
td_21, td_22 = row2.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_11.position_x == td_21.position_x == 6 # 5 + spacing
assert td_11.width == 12 # 4 + 2 * 5 - 2 * 1
assert td_21.width == 4
assert td_12.position_x == td_22.position_x == 21 # 6 + 4 + 2 * b1 + sp
assert td_12.width == 4
assert td_22.width == 10 # 4 + 2 * 3
assert table.width == 27 # 3 * spacing + 4 + 4 + 2 * b1 + 2 * b2
@assert_no_logs
def test_layout_table_auto_5():
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
* { font-family: weasyprint }
</style>
<table style="width: 1000px; font-family: weasyprint">
<tr>
<td style="width: 40px">aa aa aa aa</td>
<td style="width: 40px">aaaaaaaaaaa</td>
<td>This will take the rest of the width</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2, td_3 = row.children
assert table.width == 1000
assert td_1.width == 40
assert td_2.width == 11 * 16
assert td_3.width == 1000 - 40 - 11 * 16
@assert_no_logs
def test_layout_table_auto_6():
page, = render_pages('''
<style>
@page { size: 100px 1000px; }
</style>
<table style="border-spacing: 1px; margin-right: 79px; font-size: 0">
<tr>
<td><img src=pattern.png></td>
<td>
<img src=pattern.png> <img src=pattern.png>
<img src=pattern.png> <img src=pattern.png>
<img src=pattern.png> <img src=pattern.png>
<img src=pattern.png> <img src=pattern.png>
<img src=pattern.png>
</td>
</tr>
<tr>
<td></td>
</tr>
</table>
''')
# Preferred minimum width is 2 * 4 + 3 * 1 = 11
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row1, row2 = row_group.children
td_11, td_12 = row1.children
td_21, = row2.children
assert table_wrapper.position_x == 0
assert table.position_x == 0
assert td_11.position_x == td_21.position_x == 1 # spacing
assert td_11.width == td_21.width == 4 # minimum width
assert td_12.position_x == 6 # 1 + 5 + sp
assert td_12.width == 14 # available width
assert table.width == 21
@assert_no_logs
def test_layout_table_auto_7():
page, = render_pages('''
<table style="border-spacing: 10px; margin: 5px">
<colgroup>
<col style="width: 20px" />
</colgroup>
<tr>
<td></td>
<td style="width: 40px">a</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 15 # 0 + border-spacing
assert td_1.width == 20
assert td_2.position_x == 45 # 15 + 20 + border-spacing
assert td_2.width == 40
assert table.width == 90 # 20 + 40 + 3 * border-spacing
@assert_no_logs
def test_layout_table_auto_8():
page, = render_pages('''
<table style="border-spacing: 10px; width: 120px; margin: 5px;
font-size: 0">
<tr>
<td style="width: 20px"><img src=pattern.png></td>
<td><img src=pattern.png style="width: 40px"></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 15 # 5 + border-spacing
assert td_1.width == 20 # fixed
assert td_2.position_x == 45 # 15 + 20 + border-spacing
assert td_2.width == 70 # 120 - 3 * border-spacing - 20
assert table.width == 120
@assert_no_logs
def test_layout_table_auto_9():
page, = render_pages('''
<table style="border-spacing: 10px; width: 110px; margin: 5px">
<tr>
<td style="width: 60px"></td>
<td></td>
</tr>
<tr>
<td style="width: 50px"></td>
<td style="width: 30px"></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row_1, row_2 = row_group.children
td_1, td_2 = row_1.children
td_3, td_4 = row_2.children
assert table_wrapper.position_x == 0
assert table.position_x == 5 # 0 + margin-left
assert td_1.position_x == 15 # 0 + border-spacing
assert td_3.position_x == 15
assert td_1.width == 60
assert td_2.width == 30
assert td_2.position_x == 85 # 15 + 60 + border-spacing
assert td_4.position_x == 85
assert td_3.width == 60
assert td_4.width == 30
assert table.width == 120 # 60 + 30 + 3 * border-spacing
@assert_no_logs
def test_layout_table_auto_10():
page, = render_pages('''
<table style="border-spacing: 0; width: 14px; margin: 10px">
<colgroup>
<col />
<col style="width: 6px" />
</colgroup>
<tr>
<td><img src=pattern.png><img src=pattern.png></td>
<td style="width: 8px"></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 10 # 0 + margin-left
assert td_1.position_x == 10
assert td_1.width == 6 # 14 - 8
assert td_2.position_x == 16 # 10 + 6
assert td_2.width == 8 # maximum of the minimum widths for the column
assert table.width == 14
@assert_no_logs
def test_layout_table_auto_11():
page, = render_pages('''
<table style="border-spacing: 0">
<tr>
<td style="width: 10px"></td>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="2" style="width: 22px"></td>
<td style="width: 8px"></td>
<td style="width: 8px"></td>
</tr>
<tr>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row1, row2, row3 = row_group.children
td_11, td_12 = row1.children
td_21, td_22, td_23 = row2.children
td_31, td_32, td_33 = row3.children
assert table_wrapper.position_x == 0
assert table.position_x == 0
assert td_11.width == 10 # fixed
assert td_12.width == 28 # 38 - 10
assert td_21.width == 22 # fixed
assert td_22.width == 8 # fixed
assert td_23.width == 8 # fixed
assert td_31.width == 10 # same as first line
assert td_32.width == 12 # 22 - 10
assert td_33.width == 16 # 8 + 8 from second line
assert table.width == 38
@assert_no_logs
def test_layout_table_auto_12():
page, = render_pages('''
<table style="border-spacing: 10px">
<tr>
<td style="width: 10px"></td>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="2" style="width: 32px"></td>
<td style="width: 8px"></td>
<td style="width: 8px"></td>
</tr>
<tr>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row1, row2, row3 = row_group.children
td_11, td_12 = row1.children
td_21, td_22, td_23 = row2.children
td_31, td_32, td_33 = row3.children
assert table_wrapper.position_x == 0
assert table.position_x == 0
assert td_11.width == 10 # fixed
assert td_12.width == 48 # 32 - 10 - sp + 2 * 8 + 2 * sp
assert td_21.width == 32 # fixed
assert td_22.width == 8 # fixed
assert td_23.width == 8 # fixed
assert td_31.width == 10 # same as first line
assert td_32.width == 12 # 32 - 10 - sp
assert td_33.width == 26 # 2 * 8 + sp
assert table.width == 88
@assert_no_logs
def test_layout_table_auto_13():
# Regression tests: these used to crash
page, = render_pages('''
<table style="width: 30px">
<tr>
<td colspan=2></td>
<td></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 20 # 2 / 3 * 30
assert td_2.width == 10 # 1 / 3 * 30
assert table.width == 30
@assert_no_logs
def test_layout_table_auto_14():
page, = render_pages('''
<table style="width: 20px">
<col />
<col />
<tr>
<td></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, = row.children
assert td_1.width == 20
assert table.width == 20
@assert_no_logs
def test_layout_table_auto_15():
page, = render_pages('''
<table style="width: 20px">
<col />
<col />
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
column_group, = table.column_groups
column_1, column_2 = column_group.children
assert column_1.width == 0
assert column_2.width == 0
@assert_no_logs
def test_layout_table_auto_16():
# Absolute table
page, = render_pages('''
<table style="width: 30px; position: absolute">
<tr>
<td colspan=2></td>
<td></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 20 # 2 / 3 * 30
assert td_2.width == 10 # 1 / 3 * 30
assert table.width == 30
@assert_no_logs
def test_layout_table_auto_17():
# With border-collapse
page, = render_pages('''
<style>
/* Do not apply: */
colgroup, col, tbody, tr, td { margin: 1000px }
</style>
<table style="border-collapse: collapse; border: 10px solid;
/* ignored with collapsed borders: */
border-spacing: 10000px; padding: 1000px">
<colgroup>
<col style="width: 30px" />
</colgroup>
<tbody>
<tr>
<td style="padding: 2px"></td>
<td style="width: 34px; padding: 10px; border: 2px solid"></td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert table_wrapper.position_x == 0
assert table.position_x == 0
assert table.border_left_width == 5 # half of the collapsed 10px border
assert td_1.position_x == 5 # border-spacing is ignored
assert td_1.margin_width() == 30 # as <col>
assert td_1.width == 20 # 30 - 5 (border-left) - 1 (border-right) - 2*2
assert td_2.position_x == 35
assert td_2.width == 34
assert td_2.margin_width() == 60 # 34 + 2*10 + 5 + 1
assert table.width == 90 # 30 + 60
assert table.margin_width() == 100 # 90 + 2*5 (border)
@assert_no_logs
def test_layout_table_auto_18():
# Column widths as percentage
page, = render_pages('''
<table style="width: 200px">
<colgroup>
<col style="width: 70%" />
<col style="width: 30%" />
</colgroup>
<tbody>
<tr>
<td>a</td>
<td>abc</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 140
assert td_2.width == 60
assert table.width == 200
@assert_no_logs
def test_layout_table_auto_19():
# Column group width
page, = render_pages('''
<table style="width: 200px">
<colgroup style="width: 100px">
<col />
<col />
</colgroup>
<col style="width: 100px" />
<tbody>
<tr>
<td>a</td>
<td>a</td>
<td>abc</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2, td_3 = row.children
assert td_1.width == 100
assert td_2.width == 100
assert td_3.width == 100
assert table.width == 300
@assert_no_logs
def test_layout_table_auto_20():
# Multiple column width
page, = render_pages('''
<table style="width: 200px">
<colgroup>
<col style="width: 50px" />
<col style="width: 30px" />
<col />
</colgroup>
<tbody>
<tr>
<td>a</td>
<td>a</td>
<td>abc</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2, td_3 = row.children
assert td_1.width == 50
assert td_2.width == 30
assert td_3.width == 120
assert table.width == 200
@assert_no_logs
def test_layout_table_auto_21():
# Fixed-width table with column group with widths as percentages and pixels
page, = render_pages('''
<table style="width: 500px">
<colgroup style="width: 100px">
<col />
<col />
</colgroup>
<colgroup style="width: 30%">
<col />
<col />
</colgroup>
<tbody>
<tr>
<td>a</td>
<td>a</td>
<td>abc</td>
<td>abc</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2, td_3, td_4 = row.children
assert td_1.width == 100
assert td_2.width == 100
assert td_3.width == 150
assert td_4.width == 150
assert table.width == 500
@assert_no_logs
def test_layout_table_auto_22():
# Auto-width table with column group with widths as percentages and pixels
page, = render_pages('''
<table>
<colgroup style="width: 10%">
<col />
<col />
</colgroup>
<colgroup style="width: 200px">
<col />
<col />
</colgroup>
<tbody>
<tr>
<td>a a</td>
<td>a b</td>
<td>a c</td>
<td>a d</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2, td_3, td_4 = row.children
assert td_1.width == 50
assert td_2.width == 50
assert td_3.width == 200
assert td_4.width == 200
assert table.width == 500
@assert_no_logs
def test_layout_table_auto_23():
# Wrong column group width
page, = render_pages('''
<table style="width: 200px">
<colgroup style="width: 20%">
<col />
<col />
</colgroup>
<tbody>
<tr>
<td>a</td>
<td>a</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 100
assert td_2.width == 100
assert table.width == 200
@assert_no_logs
def test_layout_table_auto_24():
# Column width as percentage and cell width in pixels
page, = render_pages('''
<table style="width: 200px">
<colgroup>
<col style="width: 70%" />
<col />
</colgroup>
<tbody>
<tr>
<td>a</td>
<td style="width: 60px">abc</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 140
assert td_2.width == 60
assert table.width == 200
@assert_no_logs
def test_layout_table_auto_25():
# Column width and cell width as percentage
page, = render_pages('''
<div style="width: 400px">
<table style="width: 50%">
<colgroup>
<col style="width: 70%" />
<col />
</colgroup>
<tbody>
<tr>
<td>a</td>
<td style="width: 30%">abc</td>
</tr>
</tbody>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 140
assert td_2.width == 60
assert table.width == 200
@assert_no_logs
def test_layout_table_auto_26():
# Test regression: https://github.com/Kozea/WeasyPrint/issues/307
# Table with a cell larger than the table's max-width
page, = render_pages('''
<table style="max-width: 300px">
<td style="width: 400px"></td>
</table>
''')
@assert_no_logs
def test_layout_table_auto_27():
# Table with a cell larger than the table's width
page, = render_pages('''
<table style="width: 300px">
<td style="width: 400px"></td>
</table>
''')
@assert_no_logs
def test_layout_table_auto_28():
# Table with a cell larger than the table's width and max-width
page, = render_pages('''
<table style="width: 300px; max-width: 350px">
<td style="width: 400px"></td>
</table>
''')
@assert_no_logs
def test_layout_table_auto_29():
# Table with a cell larger than the table's width and max-width
page, = render_pages('''
<table style="width: 300px; max-width: 350px">
<td style="padding: 50px">
<div style="width: 300px"></div>
</td>
</table>
''')
@assert_no_logs
def test_layout_table_auto_30():
# Table with a cell larger than the table's max-width
page, = render_pages('''
<table style="max-width: 300px; margin: 100px">
<td style="width: 400px"></td>
</table>
''')
@assert_no_logs
def test_layout_table_auto_31():
# Test a table with column widths < table width < column width + spacing
page, = render_pages('''
<table style="width: 300px; border-spacing: 2px">
<td style="width: 299px"></td>
</table>
''')
@assert_no_logs
def test_layout_table_auto_32():
# Table with a cell larger than the table's width
page, = render_pages('''
<table style="width: 300px; margin: 100px">
<td style="width: 400px"></td>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
assert table_wrapper.margin_width() == 600 # 400 + 2 * 100
@assert_no_logs
def test_layout_table_auto_33():
# Div with auto width containing a table with a min-width
page, = render_pages('''
<div style="float: left">
<table style="min-width: 400px; margin: 100px">
<td></td>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
assert div.margin_width() == 600 # 400 + 2 * 100
assert table_wrapper.margin_width() == 600 # 400 + 2 * 100
@assert_no_logs
def test_layout_table_auto_34():
# Div with auto width containing an empty table with a min-width
page, = render_pages('''
<div style="float: left">
<table style="min-width: 400px; margin: 100px"></table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
assert div.margin_width() == 600 # 400 + 2 * 100
assert table_wrapper.margin_width() == 600 # 400 + 2 * 100
@assert_no_logs
def test_layout_table_auto_35():
# Div with auto width containing a table with a cell larger than the
# table's max-width
page, = render_pages('''
<div style="float: left">
<table style="max-width: 300px; margin: 100px">
<td style="width: 400px"></td>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
assert div.margin_width() == 600 # 400 + 2 * 100
assert table_wrapper.margin_width() == 600 # 400 + 2 * 100
@assert_no_logs
def test_layout_table_auto_36():
# Test regression on a crash: https://github.com/Kozea/WeasyPrint/pull/152
page, = render_pages('''
<table>
<td style="width: 50%">
</table>
''')
@assert_no_logs
def test_layout_table_auto_37():
# Other crashes: https://github.com/Kozea/WeasyPrint/issues/305
page, = render_pages('''
<table>
<tr>
<td>
<table>
<tr>
<th>Test</th>
</tr>
<tr>
<td style="min-width: 100%;"></td>
<td style="width: 48px;"></td>
</tr>
</table>
</td>
</tr>
</table>
''')
@assert_no_logs
def test_layout_table_auto_38():
page, = render_pages('''
<table>
<tr>
<td>
<table>
<tr>
<td style="width: 100%;"></td>
<td style="width: 48px;">
<img src="icon.png">
</td>
</tr>
</table>
</td>
</tr>
</table>
''')
@assert_no_logs
def test_layout_table_auto_39():
page, = render_pages('''
<table>
<tr>
<td>
<table style="display: inline-table">
<tr>
<td style="width: 100%;"></td>
<td></td>
</tr>
</table>
</td>
</tr>
</table>
''')
@assert_no_logs
def test_layout_table_auto_40():
# Test regression: https://github.com/Kozea/WeasyPrint/issues/368
# Check that white-space is used for the shrink-to-fit algorithm
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
</style>
<table style="width: 0">
<td style="font-family: weasyprint; white-space: nowrap">a a</td>
</table>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
table, = table_wrapper.children
assert table.width == 16 * 3
@assert_no_logs
def test_layout_table_auto_41():
# Cell width as percentage in auto-width table
page, = render_pages('''
<div style="width: 100px">
<table>
<tbody>
<tr>
<td>a a a a a a a a</td>
<td style="width: 30%">a a a a a a a a</td>
</tr>
</tbody>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 70
assert td_2.width == 30
assert table.width == 100
@assert_no_logs
def test_layout_table_auto_42():
# Cell width as percentage in auto-width table
page, = render_pages('''
<table>
<tbody>
<tr>
<td style="width: 70px">a a a a a a a a</td>
<td style="width: 30%">a a a a a a a a</td>
</tr>
</tbody>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 70
assert td_2.width == 30
assert table.width == 100
@assert_no_logs
def test_layout_table_auto_43():
# Cell width as percentage on colspan cell in auto-width table
page, = render_pages('''
<div style="width: 100px">
<table>
<tbody>
<tr>
<td>a a a a a a a a</td>
<td style="width: 30%" colspan=2>a a a a a a a a</td>
<td>a a a a a a a a</td>
</tr>
</tbody>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2, td_3 = row.children
assert td_1.width == 35
assert td_2.width == 30
assert td_3.width == 35
assert table.width == 100
@assert_no_logs
def test_layout_table_auto_44():
# Cells widths as percentages on normal and colspan cells
page, = render_pages('''
<div style="width: 100px">
<table>
<tbody>
<tr>
<td>a a a a a a a a</td>
<td style="width: 30%" colspan=2>a a a a a a a a</td>
<td>a a a a a a a a</td>
<td style="width: 40%">a a a a a a a a</td>
<td>a a a a a a a a</td>
</tr>
</tbody>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2, td_3, td_4, td_5 = row.children
assert td_1.width == 10
assert td_2.width == 30
assert td_3.width == 10
assert td_4.width == 40
assert td_5.width == 10
assert table.width == 100
@assert_no_logs
def test_layout_table_auto_45():
# Cells widths as percentage on multiple lines
page, = render_pages('''
<div style="width: 1000px">
<table>
<tbody>
<tr>
<td>a a a a a a a a</td>
<td style="width: 30%">a a a a a a a a</td>
<td>a a a a a a a a</td>
<td style="width: 40%">a a a a a a a a</td>
<td>a a a a a a a a</td>
</tr>
<tr>
<td style="width: 31%" colspan=2>a a a a a a a a</td>
<td>a a a a a a a a</td>
<td style="width: 42%" colspan=2>a a a a a a a a</td>
</tr>
</tbody>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
table, = table_wrapper.children
row_group, = table.children
row_1, row_2 = row_group.children
td_11, td_12, td_13, td_14, td_15 = row_1.children
td_21, td_22, td_23 = row_2.children
assert td_11.width == 10 # 31% - 30%
assert td_12.width == 300 # 30%
assert td_13.width == 270 # 1000 - 31% - 42%
assert td_14.width == 400 # 40%
assert td_15.width == 20 # 42% - 2%
assert td_21.width == 310 # 31%
assert td_22.width == 270 # 1000 - 31% - 42%
assert td_23.width == 420 # 42%
assert table.width == 1000
@assert_no_logs
def test_layout_table_auto_46():
# Test regression:
# https://test.weasyprint.org/suite-css21/chapter8/section2/test56/
page, = render_pages('''
<div style="position: absolute">
<table style="margin: 50px; border: 20px solid black">
<tr>
<td style="width: 200px; height: 200px"></td>
</tr>
</table>
</div>
''')
html, = page.children
body, = html.children
div, = body.children
table_wrapper, = div.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td, = row.children
assert td.width == 200
assert table.width == 200
assert div.width == 340 # 200 + 2 * 50 + 2 * 20
@assert_no_logs
def test_layout_table_auto_47():
# Test regression:
# https://github.com/Kozea/WeasyPrint/issues/666
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
</style>
<table style="font-family: weasyprint">
<tr>
<td colspan=5>aaa</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td, = row.children
assert td.width == 48 # 3 * font-size
@assert_no_logs
def test_layout_table_auto_48():
# Related to:
# https://github.com/Kozea/WeasyPrint/issues/685
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
</style>
<table style="font-family: weasyprint; border-spacing: 100px;
border-collapse: collapse">
<tr>
<td colspan=5>aaa</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td, = row.children
assert td.width == 48 # 3 * font-size
@pytest.mark.xfail
@assert_no_logs
def test_layout_table_auto_49():
# Related to:
# https://github.com/Kozea/WeasyPrint/issues/685
# See TODO in table_layout.group_layout
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
</style>
<table style="font-family: weasyprint; border-spacing: 100px">
<tr>
<td colspan=5>aaa</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td, = row.children
assert td.width == 48 # 3 * font-size
@assert_no_logs
def test_layout_table_auto_50():
# Test regression:
# https://github.com/Kozea/WeasyPrint/issues/685
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
</style>
<table style="font-family: weasyprint; border-spacing: 5px">
<tr><td>a</td><td>a</td><td>a</td><td>a</td><td>a</td></tr>
<tr>
<td colspan='5'>aaa aaa aaa aaa</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row_1, row_2 = row_group.children
for td in row_1.children:
assert td.width == 44 # (15 * font_size - 4 * sp) / 5
td_21, = row_2.children
assert td_21.width == 240 # 15 * font_size
@assert_no_logs
@pytest.mark.parametrize(
'body_width, table_width, check_width, positions, widths', (
('500px', '230px', 220, [170, 5], [45, 155]),
('530px', '100%', 520, [395, 5], [120, 380]),
)
)
def test_explicit_width_table_percent_rtl(body_width, table_width, check_width,
positions, widths):
page, = render_pages('''
<style>
body { width: %s }
table { width: %s; table-layout: fixed; direction: rtl;
border-collapse: collapse; font-size: 1px }
td, th { border: 10px solid }
</style>
<table style="">
<col style="width: 25%%"></col>
<col></col>
<tr>
<th>الاسم</th>
<th>العائلة</th>
</tr>
<tr>
<td>محمد يوسف</td>
<td>29</td>
</tr>
</table>
''' % (body_width, table_width))
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
row_group, = table.children
row_1, row_2 = row_group.children
assert table.position_x == 0
assert table.width == check_width
assert [child.position_x for child in row_1.children] == positions
assert [child.position_x for child in row_2.children] == positions
assert [child.width for child in row_1.children] == widths
assert [child.width for child in row_2.children] == widths
@assert_no_logs
def test_table_column_width_1():
source = '''
<style>
body { width: 20000px; margin: 0 }
table {
width: 10000px; margin: 0 auto; border-spacing: 100px 0;
table-layout: fixed
}
td { border: 10px solid; padding: 1px }
</style>
<table>
<col style="width: 10%">
<tr>
<td style="width: 30%" colspan=3>
<td>
</tr>
<tr>
<td>
<td>
<td>
<td>
</tr>
<tr>
<td>
<td colspan=12>This cell will be truncated to grid width
<td>This cell will be removed as it is beyond the grid width
</tr>
</table>
'''
with capture_logs() as logs:
page, = render_pages(source)
assert len(logs) == 1
assert logs[0].startswith('WARNING: This table row has more columns than '
'the table, ignored 1 cell')
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
row_group, = table.children
first_row, second_row, third_row = row_group.children
cells = [first_row.children, second_row.children, third_row.children]
assert len(first_row.children) == 2
assert len(second_row.children) == 4
# Third cell here is completly removed
assert len(third_row.children) == 2
assert body.position_x == 0
assert wrapper.position_x == 0
assert wrapper.margin_left == 5000
assert wrapper.content_box_x() == 5000 # auto margin-left
assert wrapper.width == 10000
assert table.position_x == 5000
assert table.width == 10000
assert row_group.position_x == 5100 # 5000 + border_spacing
assert row_group.width == 9800 # 10000 - 2*border-spacing
assert first_row.position_x == row_group.position_x
assert first_row.width == row_group.width
# This cell has colspan=3
assert cells[0][0].position_x == 5100 # 5000 + border-spacing
# `width` on a cell sets the content width
assert cells[0][0].width == 3000 # 30% of 10000px
assert cells[0][0].border_width() == 3022 # 3000 + borders + padding
# Second cell of the first line, but on the fourth and last column
assert cells[0][1].position_x == 8222 # 5100 + 3022 + border-spacing
assert cells[0][1].border_width() == 6678 # 10000 - 3022 - 3*100
assert cells[0][1].width == 6656 # 6678 - borders - padding
assert cells[1][0].position_x == 5100 # 5000 + border-spacing
# `width` on a column sets the border width of cells
assert cells[1][0].border_width() == 1000 # 10% of 10000px
assert cells[1][0].width == 978 # 1000 - borders - padding
assert cells[1][1].position_x == 6200 # 5100 + 1000 + border-spacing
assert cells[1][1].border_width() == 911 # (3022 - 1000 - 2*100) / 2
assert cells[1][1].width == 889 # 911 - borders - padding
assert cells[1][2].position_x == 7211 # 6200 + 911 + border-spacing
assert cells[1][2].border_width() == 911 # (3022 - 1000 - 2*100) / 2
assert cells[1][2].width == 889 # 911 - borders - padding
# Same as cells[0][1]
assert cells[1][3].position_x == 8222 # Also 7211 + 911 + border-spacing
assert cells[1][3].border_width() == 6678
assert cells[1][3].width == 6656
# Same as cells[1][0]
assert cells[2][0].position_x == 5100
assert cells[2][0].border_width() == 1000
assert cells[2][0].width == 978
assert cells[2][1].position_x == 6200 # Same as cells[1][1]
assert cells[2][1].border_width() == 8700 # 1000 - 1000 - 3*border-spacing
assert cells[2][1].width == 8678 # 8700 - borders - padding
assert cells[2][1].colspan == 3 # truncated to grid width
@assert_no_logs
def test_table_column_width_2():
page, = render_pages('''
<style>
table { width: 1000px; border-spacing: 100px; table-layout: fixed }
</style>
<table>
<tr>
<td style="width: 50%">
<td style="width: 60%">
<td>
</tr>
</table>
''')
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
row_group, = table.children
row, = row_group.children
assert row.children[0].width == 500
assert row.children[1].width == 600
assert row.children[2].width == 0
assert table.width == 1500 # 500 + 600 + 4 * border-spacing
@assert_no_logs
def test_table_column_width_3():
# Sum of columns width larger that the table width:
# increase the table width
page, = render_pages('''
<style>
table { width: 1000px; border-spacing: 100px; table-layout: fixed }
td { width: 60% }
</style>
<table>
<tr>
<td>
<td>
</tr>
</table>
''')
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
row_group, = table.children
row, = row_group.children
cell_1, cell_2 = row.children
assert cell_1.width == 600 # 60% of 1000px
assert cell_2.width == 600
assert table.width == 1500 # 600 + 600 + 3*border-spacing
assert wrapper.width == table.width
@assert_no_logs
def test_table_row_height_1():
page, = render_pages('''
<table style="width: 1000px; border-spacing: 0 100px;
font: 20px/1em serif; margin: 3px; table-layout: fixed">
<tr>
<td rowspan=0 style="height: 420px; vertical-align: top"></td>
<td>X<br>X<br>X</td>
<td><table style="margin-top: 20px; border-spacing: 0">
<tr><td>X</td></tr></table></td>
<td style="vertical-align: top">X</td>
<td style="vertical-align: middle">X</td>
<td style="vertical-align: bottom">X</td>
</tr>
<tr>
<!-- cells with no text (no line boxes) is a corner case
in cell baselines -->
<td style="padding: 15px"></td>
<td><div style="height: 10px"></div></td>
</tr>
<tr></tr>
<tr>
<td style="vertical-align: bottom"></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
row_group, = table.children
assert wrapper.position_y == 0
assert table.position_y == 3 # 0 + margin-top
assert table.height == 620 # sum of row heigths + 5*border-spacing
assert wrapper.height == table.height
assert row_group.position_y == 103 # 3 + border-spacing
assert row_group.height == 420 # 620 - 2*border-spacing
assert [row.height for row in row_group.children] == [
80, 30, 0, 10]
assert [row.position_y for row in row_group.children] == [
# cumulative sum of previous row heights and border-spacings
103, 283, 413, 513]
assert [[cell.height for cell in row.children]
for row in row_group.children] == [
[420, 60, 40, 20, 20, 20],
[0, 10],
[],
[0]
]
assert [[cell.border_height() for cell in row.children]
for row in row_group.children] == [
[420, 80, 80, 80, 80, 80],
[30, 30],
[],
[10]
]
# The baseline of the first row is at 40px because of the third column.
# The second column thus gets a top padding of 20px pushes the bottom
# to 80px.The middle is at 40px.
assert [[cell.padding_top for cell in row.children]
for row in row_group.children] == [
[0, 20, 0, 0, 30, 60],
[15, 5],
[],
[10]
]
assert [[cell.padding_bottom for cell in row.children]
for row in row_group.children] == [
[0, 0, 40, 60, 30, 0],
[15, 15],
[],
[0]
]
assert [[cell.position_y for cell in row.children]
for row in row_group.children] == [
[103, 103, 103, 103, 103, 103],
[283, 283],
[],
[513]
]
@assert_no_logs
def test_table_row_height_2():
# A cell box cannot extend beyond the last row box of a table.
page, = render_pages('''
<table style="border-spacing: 0">
<tr style="height: 10px">
<td rowspan=5></td>
<td></td>
</tr>
<tr style="height: 10px">
<td></td>
</tr>
</table>
''')
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
row_group, = table.children
@assert_no_logs
def test_table_row_height_3():
# Test regression: https://github.com/Kozea/WeasyPrint/issues/937
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
</style>
<table style="border-spacing: 0; font-family: weasyprint;
line-height: 20px">
<tr><td>Table</td><td rowspan="2"></td></tr>
<tr></tr>
</table>
''')
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
assert table.height == 20
row_group, = table.children
assert row_group.height == 20
row1, row2 = row_group.children
assert row1.height == 20
assert row2.height == 0
@assert_no_logs
def test_table_vertical_align(assert_pixels):
assert_pixels('''
rrrrrrrrrrrrrrrrrrrrrrrrrrrr
rBBBBBBBBBBBBBBBBBBBBBBBBBBr
rBrBB_BB_BB_BB_BBrrBBrrBB_Br
rBrBB_BB_BBrBBrBBrrBBrrBBrBr
rB_BBrBB_BBrBBrBBrrBBrrBBrBr
rB_BBrBB_BB_BB_BBrrBBrrBB_Br
rB_BB_BBrBB_BB_BB__BB__BB_Br
rB_BB_BBrBB_BB_BB__BB__BB_Br
rBBBBBBBBBBBBBBBBBBBBBBBBBBr
rrrrrrrrrrrrrrrrrrrrrrrrrrrr
''', '''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
@page { size: 28px 10px }
html { font-size: 1px; color: red }
body { margin: 0; width: 28px; height: 10px }
td {
width: 1em;
padding: 0 !important;
border: 1px solid blue;
line-height: 1em;
font-family: weasyprint;
}
</style>
<table style="border: 1px solid red; border-spacing: 0">
<tr>
<!-- Test vertical-align: top, auto height -->
<td style="vertical-align: top">o o</td>
<!-- Test vertical-align: middle, auto height -->
<td style="vertical-align: middle">o o</td>
<!-- Test vertical-align: bottom, fixed useless height -->
<td style="vertical-align: bottom; height: 2em">o o</td>
<!-- Test default vertical-align value (baseline),
fixed useless height -->
<td style="height: 5em">o o</td>
<!-- Test vertical-align: baseline with baseline set by next cell,
auto height -->
<td style="vertical-align: baseline">o o</td>
<!-- Set baseline height to 2px, auto height -->
<td style="vertical-align: baseline; font-size: 2em">o o</td>
<!-- Test padding-bottom, fixed useless height,
set the height of the cells to 2 lines * 2em + 2px = 6px -->
<td style="vertical-align: baseline; height: 1em;
font-size: 2em; padding-bottom: 2px !important">
o o
</td>
<!-- Test padding-top, auto height -->
<td style="vertical-align: top; padding-top: 1em !important">
o o
</td>
</tr>
</table>
''') # noqa
@assert_no_logs
def test_table_wrapper():
page, = render_pages('''
<style>
@page { size: 1000px }
table { width: 600px; height: 500px; table-layout: fixed;
padding: 1px; border: 10px solid; margin: 100px; }
</style>
<table></table>
''')
html, = page.children
body, = html.children
wrapper, = body.children
table, = wrapper.children
assert body.width == 1000
assert wrapper.width == 600 # Not counting borders or padding
assert wrapper.margin_left == 100
assert table.margin_width() == 600
assert table.width == 578 # 600 - 2*10 - 2*1, no margin
# box-sizing in the UA stylesheet makes `height: 500px` set this
assert table.border_height() == 500
assert table.height == 478 # 500 - 2*10 - 2*1
assert table.margin_height() == 500 # no margin
assert wrapper.height == 500
assert wrapper.margin_height() == 700 # 500 + 2*100
@assert_no_logs
def test_table_html_tag():
# Non-regression test: this used to cause an exception
page, = render_pages('<html style="display: table">')
@assert_no_logs
@pytest.mark.parametrize('html, rows, positions', (
('''
<style>
@page { size: 120px }
table { table-layout: fixed; width: 100% }
h1 { height: 30px }
td { height: 40px }
</style>
<h1>Dummy title</h1>
<table>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
<tr><td>row 4</td></tr>
<tr><td>row 5</td></tr>
<tr><td style="height: 300px"> <!-- overflow the page -->
row 6</td></tr>
<tr><td>row 7</td></tr>
<tr><td>row 8</td></tr>
</table>
''',
[2, 3, 1, 2],
[30, 70, 0, 40, 80, 0, 0, 40]),
('''
<style>
@page { size: 120px }
h1 { height: 30px}
td { height: 40px }
table { table-layout: fixed; width: 100%;
page-break-inside: avoid }
</style>
<h1>Dummy title</h1>
<table>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
<tr><td>row 4</td></tr>
</table>
''',
[0, 3, 1],
[0, 40, 80, 0]),
('''
<style>
@page { size: 120px }
h1 { height: 30px}
td { height: 40px }
table { table-layout: fixed; width: 100%;
page-break-inside: avoid }
</style>
<h1>Dummy title</h1>
<table>
<tbody>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tr><td>row 4</td></tr>
</table>
''',
[0, 3, 1],
[0, 40, 80, 0]),
('''
<style>
@page { size: 120px }
h1 { height: 30px}
td { height: 40px }
table { table-layout: fixed; width: 100% }
</style>
<h1>Dummy title</h1>
<table>
<tr><td>row 1</td></tr>
<tbody style="page-break-inside: avoid">
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
</table>
''',
[1, 2],
[30, 0, 40]),
('''
<style>
@page { size: 120px }
h1 { height: 30px}
td { line-height: 40px }
table { table-layout: fixed; width: 100% }
</style>
<h1>Dummy title</h1>
<table>
<tr><td>r1l1</td></tr>
<tr style="break-inside: avoid"><td>r2l1<br>r2l2</td></tr>
<tr><td>r3l1</td></tr>
</table>
''',
[1, 2],
[30, 0, 80]),
('''
<style>
@page { size: 120px }
h1 { height: 30px}
td { line-height: 40px }
table { table-layout: fixed; width: 100% }
</style>
<h1>Dummy title</h1>
<table>
<tbody>
<tr><td>r1l1</td></tr>
<tr style="break-inside: avoid"><td>r2l1<br>r2l2</td></tr>
</tbody>
<tr><td>r3l1</td></tr>
</table>
''',
[1, 2],
[30, 0, 80]),
))
def test_table_page_breaks(html, rows, positions):
pages = render_pages(html)
rows_per_page = []
rows_position_y = []
for i, page in enumerate(pages):
html, = page.children
body, = html.children
if i == 0:
body_children = body.children[1:] # skip h1
else:
body_children = body.children
if not body_children:
rows_per_page.append(0)
continue
table_wrapper, = body_children
table, = table_wrapper.children
rows_in_this_page = 0
for group in table.children:
assert group.children, 'found an empty table group'
for row in group.children:
rows_in_this_page += 1
rows_position_y.append(row.position_y)
cell, = row.children
rows_per_page.append(rows_in_this_page)
assert rows_per_page == rows
assert rows_position_y == positions
@assert_no_logs
def test_table_page_breaks_complex_1():
pages = render_pages('''
<style>
@page { size: 100px }
</style>
<h1 style="margin: 0; height: 30px">Lipsum</h1>
<!-- Leave 70px on the first page: enough for the header or row1
but not both. -->
<table style="border-spacing: 0; font-size: 5px">
<thead>
<tr><td style="height: 20px">Header</td></tr>
</thead>
<tbody>
<tr><td style="height: 60px">Row 1</td></tr>
<tr><td style="height: 10px">Row 2</td></tr>
<tr><td style="height: 50px">Row 3</td></tr>
<tr><td style="height: 61px">Row 4</td></tr>
<tr><td style="height: 90px">Row 5</td></tr>
</tbody>
<tfoot>
<tr><td style="height: 20px">Footer</td></tr>
</tfoot>
</table>
''')
rows_per_page = []
for i, page in enumerate(pages):
groups = []
html, = page.children
body, = html.children
table_wrapper, = body.children
if i == 0:
assert table_wrapper.element_tag == 'h1'
else:
table, = table_wrapper.children
for group in table.children:
assert group.children, 'found an empty table group'
rows = []
for row in group.children:
cell, = row.children
line, = cell.children
text, = line.children
rows.append(text.text)
groups.append(rows)
rows_per_page.append(groups)
assert rows_per_page == [
[],
[['Header'], ['Row 1'], ['Footer']],
[['Header'], ['Row 2', 'Row 3'], ['Footer']],
[['Header'], ['Row 4']],
[['Row 5']]
]
@assert_no_logs
def test_table_page_breaks_complex_2():
pages = render_pages('''
<style>
@page { size: 250px }
td { height: 40px }
table { table-layout: fixed; width: 100%; break-before: avoid }
</style>
<table>
<thead>
<tr><td>head 1</td></tr>
</thead>
<tbody>
<tr><td>row 1 1</td></tr>
<tr><td>row 1 2</td></tr>
<tr><td>row 1 3</td></tr>
</tbody>
<tfoot>
<tr><td>foot 1</td></tr>
</tfoot>
</table>
<table>
<thead>
<tr><td>head 2</td></tr>
</thead>
<tbody>
<tr><td>row 2 1</td></tr>
<tr><td>row 2 2</td></tr>
<tr><td>row 2 3</td></tr>
</tbody>
<tfoot>
<tr><td>foot 2</td></tr>
</tfoot>
</table>
''')
rows_per_page = []
for i, page in enumerate(pages):
groups = []
html, = page.children
body, = html.children
for table_wrapper in body.children:
table, = table_wrapper.children
for group in table.children:
assert group.children, 'found an empty table group'
rows = []
for row in group.children:
cell, = row.children
line, = cell.children
text, = line.children
rows.append(text.text)
groups.append(rows)
rows_per_page.append(groups)
assert rows_per_page == [
[['head 1'], ['row 1 1', 'row 1 2'], ['foot 1']],
[['head 1'], ['row 1 3'], ['foot 1'],
['head 2'], ['row 2 1'], ['foot 2']],
[['head 2'], ['row 2 2', 'row 2 3'], ['foot 2']],
]
# TODO: test positions, the place of footer on the first page is wrong
@assert_no_logs
def test_table_page_break_after():
page1, page2, page3, page4, page5, page6 = render_pages('''
<style>
@page { size: 1000px }
h1 { height: 30px}
td { height: 40px }
table { table-layout: fixed; width: 100% }
</style>
<h1>Dummy title</h1>
<table>
<tbody>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tbody>
<tr style="break-after: page"><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tbody>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr style="break-after: page"><td>row 3</td></tr>
</tbody>
<tbody style="break-after: right">
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tbody style="break-after: page">
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
</table>
<p>bla bla</p>
''')
html, = page1.children
body, = html.children
h1, table_wrapper = body.children
table, = table_wrapper.children
table_group1, table_group2 = table.children
assert len(table_group1.children) == 3
assert len(table_group2.children) == 1
html, = page2.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
table_group1, table_group2 = table.children
assert len(table_group1.children) == 2
assert len(table_group2.children) == 3
html, = page3.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
table_group, = table.children
assert len(table_group.children) == 3
html, = page4.children
assert not html.children
html, = page5.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
table_group, = table.children
assert len(table_group.children) == 3
html, = page6.children
body, = html.children
p, = body.children
assert p.element_tag == 'p'
@assert_no_logs
def test_table_page_break_before():
page1, page2, page3, page4, page5, page6 = render_pages('''
<style>
@page { size: 1000px }
h1 { height: 30px}
td { height: 40px }
table { table-layout: fixed; width: 100% }
</style>
<h1>Dummy title</h1>
<table>
<tbody>
<tr style="break-before: page"><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tbody>
<tr><td>row 1</td></tr>
<tr style="break-before: page"><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tbody>
<tr style="break-before: page"><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tbody>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
<tbody style="break-before: left">
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
</table>
<p>bla bla</p>
''')
html, = page1.children
body, = html.children
h1, = body.children
assert h1.element_tag == 'h1'
html, = page2.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
table_group1, table_group2 = table.children
assert len(table_group1.children) == 3
assert len(table_group2.children) == 1
html, = page3.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
table_group, = table.children
assert len(table_group.children) == 2
html, = page4.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
table_group1, table_group2 = table.children
assert len(table_group1.children) == 3
assert len(table_group2.children) == 3
html, = page5.children
assert not html.children
html, = page6.children
body, = html.children
table_wrapper, p = body.children
table, = table_wrapper.children
table_group, = table.children
assert len(table_group.children) == 3
assert p.element_tag == 'p'
@assert_no_logs
@pytest.mark.parametrize('html, rows', (
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 26px }
</style>
<table>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr style="break-before: avoid"><td>row 2</td></tr>
<tr style="break-before: avoid"><td>row 3</td></tr>
</tbody>
</table>
''',
[1, 3]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 26px }
</style>
<table>
<tbody>
<tr><td>row 0</td></tr>
<tr style="break-after: avoid"><td>row 1</td></tr>
<tr><td>row 2</td></tr>
<tr style="break-before: avoid"><td>row 3</td></tr>
</tbody>
</table>
''',
[1, 3]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 26px }
</style>
<table>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr style="break-after: avoid"><td>row 2</td></tr>
<tr><td>row 3</td></tr>
</tbody>
</table>
''',
[2, 2]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 26px }
</style>
<table>
<tbody>
<tr style="break-before: avoid"><td>row 0</td></tr>
<tr style="break-before: avoid"><td>row 1</td></tr>
<tr style="break-before: avoid"><td>row 2</td></tr>
<tr style="break-before: avoid"><td>row 3</td></tr>
</tbody>
</table>
''',
[3, 1]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 26px }
</style>
<table>
<tbody>
<tr style="break-after: avoid"><td>row 0</td></tr>
<tr style="break-after: avoid"><td>row 1</td></tr>
<tr style="break-after: avoid"><td>row 2</td></tr>
<tr style="break-after: avoid"><td>row 3</td></tr>
</tbody>
</table>
''',
[3, 1]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 26px }
p { height: 26px }
</style>
<p>wow p</p>
<table>
<tbody>
<tr style="break-after: avoid"><td>row 0</td></tr>
<tr style="break-after: avoid"><td>row 1</td></tr>
<tr style="break-after: avoid"><td>row 2</td></tr>
<tr style="break-after: avoid"><td>row 3</td></tr>
</tbody>
</table>
''',
[1, 3, 1]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 30px }
</style>
<table>
<tbody style="break-after: avoid">
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
</table>
''',
[2, 3, 1]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 30px }
</style>
<table>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
<tbody style="break-before: avoid">
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
</table>
''',
[2, 3, 1]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 30px }
</style>
<table>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
<tbody>
<tr style="break-before: avoid"><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
</table>
''',
[2, 3, 1]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 30px }
</style>
<table>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr style="break-after: avoid"><td>row 2</td></tr>
</tbody>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
</table>
''',
[2, 3, 1]),
('''
<style>
@page { size: 100px }
table { table-layout: fixed; width: 100% }
tr { height: 30px }
</style>
<table>
<tbody style="break-after: avoid">
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr style="break-after: page"><td>row 2</td></tr>
</tbody>
<tbody>
<tr><td>row 0</td></tr>
<tr><td>row 1</td></tr>
<tr><td>row 2</td></tr>
</tbody>
</table>
''',
[3, 3]),
))
def test_table_page_break_avoid(html, rows):
pages = render_pages(html)
assert len(pages) == len(rows)
rows_per_page = []
for page in pages:
html, = page.children
body, = html.children
if body.children[0].element_tag == 'p':
rows_per_page.append(len(body.children))
continue
else:
table_wrapper, = body.children
table, = table_wrapper.children
rows_in_this_page = 0
for group in table.children:
for row in group.children:
rows_in_this_page += 1
rows_per_page.append(rows_in_this_page)
assert rows_per_page == rows
@assert_no_logs
@pytest.mark.parametrize('vertical_align, table_position_y', (
('top', 8),
('bottom', 8),
('baseline', 10),
))
def test_inline_table_baseline(vertical_align, table_position_y):
# Check that inline table's baseline is its first row's baseline.
#
# Div text's baseline is at 18px from the top (10px because of the
# line-height, 8px as it's weasyprint.otf's baseline position).
#
# When a row has vertical-align: baseline cells, its baseline is its cell's
# baseline. The position of the table is thus 10px above the text's
# baseline.
#
# When a row has another value for vertical-align, the baseline is the
# bottom of the row. The first cell's text is aligned with the div's text,
# and the top of the table is thus 8px above the baseline.
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
</style>
<div style="font-family: weasyprint; font-size: 10px; line-height: 30px">
abc
<table style="display: inline-table; border-collapse: collapse;
line-height: 10px">
<tr><td style="vertical-align: %s">a</td></tr>
<tr><td>a</td></tr>
</table>
abc
</div>
''' % vertical_align)
html, = page.children
body, = html.children
div, = body.children
line, = div.children
text1, table_wrapper, text2 = line.children
table, = table_wrapper.children
assert text1.position_y == text2.position_y == 0
assert table.height == 10 * 2
assert abs(table.position_y - table_position_y) < 0.1
@assert_no_logs
def test_table_caption_margin_top():
page, = render_pages('''
<style>
table { margin: 20px; }
caption, h1, h2 { margin: 20px; height: 10px }
td { height: 10px }
</style>
<h1></h1>
<table>
<caption></caption>
<tr>
<td></td>
</tr>
</table>
<h2></h2>
''')
html, = page.children
body, = html.children
h1, wrapper, h2 = body.children
caption, table = wrapper.children
tbody, = table.children
assert (h1.content_box_x(), h1.content_box_y()) == (20, 20)
assert (wrapper.content_box_x(), wrapper.content_box_y()) == (20, 50)
assert (caption.content_box_x(), caption.content_box_y()) == (40, 70)
assert (tbody.content_box_x(), tbody.content_box_y()) == (20, 100)
assert (h2.content_box_x(), h2.content_box_y()) == (20, 130)
@assert_no_logs
def test_table_caption_margin_bottom():
page, = render_pages('''
<style>
table { margin: 20px; }
caption, h1, h2 { margin: 20px; height: 10px; caption-side: bottom }
td { height: 10px }
</style>
<h1></h1>
<table>
<caption></caption>
<tr>
<td></td>
</tr>
</table>
<h2></h2>
''')
html, = page.children
body, = html.children
h1, wrapper, h2 = body.children
table, caption = wrapper.children
tbody, = table.children
assert (h1.content_box_x(), h1.content_box_y()) == (20, 20)
assert (wrapper.content_box_x(), wrapper.content_box_y()) == (20, 50)
assert (tbody.content_box_x(), tbody.content_box_y()) == (20, 50)
assert (caption.content_box_x(), caption.content_box_y()) == (40, 80)
assert (h2.content_box_x(), h2.content_box_y()) == (20, 130)
@assert_no_logs
@pytest.mark.parametrize('rows_expected, thead, tfoot, content', (
([[], ['Header', 'Footer']], 45, 45, '<p>content</p>'),
([[], ['Header', 'Footer']], 85, 5, '<p>content</p>'),
([['Header', 'Footer']], 30, 30, '<p>content</p>'),
([[], ['Header']], 30, 110, '<p>content</p>'),
([[], ['Header', 'Footer']], 30, 60, '<p>content</p>'),
([[], ['Footer']], 110, 30, '<p>content</p>'),
# We try to render the header and footer on the same page, but it does not
# fit. So we try to render the header or the footer on the next one, but
# nothing fit either.
([[], []], 110, 110, '<p>content</p>'),
([['Header', 'Footer']], 30, 30, ''),
([['Header']], 30, 110, ''),
([['Header', 'Footer']], 30, 60, ''),
([['Footer']], 110, 30, ''),
([[]], 110, 110, ''),
))
def test_table_empty_body(rows_expected, thead, tfoot, content):
html = '''
<style>
@page { size: 100px }
p { height: 20px }
thead th { height: %spx }
tfoot th { height: %spx }
</style>
%s
<table>
<thead><tr><th>Header</th></tr></thead>
<tfoot><tr><th>Footer</th></tr></tfoot>
</table>
''' % (thead, tfoot, content)
pages = render_pages(html)
assert len(pages) == len(rows_expected)
for i, page in enumerate(pages):
rows = []
html, = page.children
body, = html.children
table_wrapper = body.children[-1]
if not table_wrapper.is_table_wrapper:
assert rows == rows_expected[i]
continue
table, = table_wrapper.children
for group in table.children:
for row in group.children:
cell, = row.children
line, = cell.children
text, = line.children
rows.append(text.text)
assert rows == rows_expected[i]
def test_table_break_children_margin():
# Test regression: https://github.com/Kozea/WeasyPrint/issues/1254
html = '''
<style>
@page { size: 100px }
p { height: 20px; margin-top: 50px }
</style>
<table>
<tr><td><p>Page1</p></td></tr>
<tr><td><p>Page2</p></td></tr>
<tr><td><p>Page3</p></td></tr>
</table>
'''
assert len(render_pages(html)) == 3
def test_table_td_break_inside_avoid():
# Test regression: https://github.com/Kozea/WeasyPrint/issues/1547
html = '''
<style>
@page { size: 4cm }
td { break-inside: avoid; line-height: 3cm }
</style>
<table>
<tr>
<td>
a<br>a
</td>
</tr>
</table>
'''
assert len(render_pages(html)) == 2
@assert_no_logs
def test_table_bad_int_td_th_span():
page, = render_pages('''
<table>
<tr>
<td colspan="bad"></td>
<td rowspan="23.4"></td>
</tr>
<tr>
<th colspan="x" rowspan="-2"></th>
<th></th>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row_1, row_2 = row_group.children
td_1, td_2 = row_1.children
assert td_1.width == td_2.width
th_1, th_2 = row_2.children
assert th_1.width == th_2.width
@assert_no_logs
def test_table_bad_int_col_span():
page, = render_pages('''
<table>
<colgroup>
<col span="bad" style="width:25px" />
</colgroup>
<tr>
<td>a</td>
<td>a</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 25
@assert_no_logs
def test_table_bad_int_colgroup_span():
page, = render_pages('''
<table>
<colgroup span="bad" style="width:25px">
<col />
</colgroup>
<tr>
<td>a</td>
<td>a</td>
</tr>
</table>
''')
html, = page.children
body, = html.children
table_wrapper, = body.children
table, = table_wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
assert td_1.width == 25
@assert_no_logs
def test_table_different_display():
# Test display attribute set on different table elements
render_pages('''
<table style="font-size: 1px">
<colgroup style="display: block"><div>a</div></colgroup>
<col style="display: block"><div>a</div></col>
<tr style="display: block"><div>a</div></tr>
<td style="display: block"><div>a</div></td>
<th style="display: block"><div>a</div></th>
<thead>
<colgroup style="display: block"><div>a</div></colgroup>
<col style="display: block"><div>a</div></col>
<tr style="display: block"><div>a</div></tr>
<td style="display: block"><div>a</div></td>
<th style="display: block"><div>a</div></th>
</thead>
<tbody>
<colgroup style="display: block"><div>a</div></colgroup>
<col style="display: block"><div>a</div></col>
<tr style="display: block"><div>a</div></tr>
<td style="display: block"><div>a</div></td>
<th style="display: block"><div>a</div></th>
</tbody>
<tr>
<colgroup style="display: block"><div>a</div></colgroup>
<col style="display: block"><div>a</div></col>
<tr style="display: block"><div>a</div></tr>
<td style="display: block"><div>a</div></td>
<th style="display: block"><div>a</div></th>
</tr>
<td>
<colgroup style="display: block"><div>a</div></colgroup>
<col style="display: block"><div>a</div></col>
<tr style="display: block"><div>a</div></tr>
<td style="display: block"><div>a</div></td>
<th style="display: block"><div>a</div></th>
</td>
</table>
''')