wintrust: Simplify error handling in SoftpubLoadSignature.
[wine] / dlls / mshtml / tests / dom.c
1 /*
2  * Copyright 2007-2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "mshtml.h"
30 #include "mshtmcid.h"
31 #include "mshtmhst.h"
32 #include "docobj.h"
33 #include "dispex.h"
34 #include "mshtml_test.h"
35
36 static const char doc_blank[] = "<html></html>";
37 static const char doc_str1[] = "<html><body>test</body></html>";
38 static const char range_test_str[] =
39     "<html><body>test \na<font size=\"2\">bc\t123<br /> it's\r\n  \t</font>text<br /></body></html>";
40 static const char range_test2_str[] =
41     "<html><body>abc<hr />123<br /><hr />def</body></html>";
42 static const char elem_test_str[] =
43     "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
44     "<body onload=\"Testing()\">text test<!-- a comment -->"
45     "<a id=\"a\" href=\"http://test\" name=\"x\">link</a>"
46     "<input id=\"in\" class=\"testclass\" tabIndex=\"2\" title=\"test title\" />"
47     "<select id=\"s\"><option id=\"x\" value=\"val1\">opt1</option><option id=\"y\">opt2</option></select>"
48     "<textarea id=\"X\">text text</textarea>"
49     "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td>td1 text</td><td>td2 text</td></tr></tbody></table>"
50     "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
51     "<test />"
52     "<img id=\"imgid\" name=\"WineImg\"/>"
53     "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
54     "<form id=\"frm\"></form>"
55     "</body></html>";
56 static const char elem_test2_str[] =
57     "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
58     "<body><div id=\"divid\"></div></body>"
59     "</html>";
60
61 static const char indent_test_str[] =
62     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
63 static const char cond_comment_str[] =
64     "<html><head><title>test</title></head><body>"
65     "<!--[if gte IE 4]> <br> <![endif]-->"
66     "</body></html>";
67 static const char frameset_str[] =
68     "<html><head><title>frameset test</title></head><frameset rows=\"25, 25, *\">"
69     "<frame src=\"about:blank\" name=\"nm1\" id=\"fr1\"><frame src=\"about:blank\" name=\"nm2\" id=\"fr2\">"
70     "<frame src=\"about:blank\" id=\"fr3\">"
71     "</frameset></html>";
72
73 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
74 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
75 static WCHAR wordW[] = {'w','o','r','d',0};
76
77 typedef enum {
78     ET_NONE,
79     ET_HTML,
80     ET_HEAD,
81     ET_TITLE,
82     ET_BODY,
83     ET_A,
84     ET_INPUT,
85     ET_SELECT,
86     ET_TEXTAREA,
87     ET_OPTION,
88     ET_STYLE,
89     ET_BLOCKQUOTE,
90     ET_P,
91     ET_BR,
92     ET_TABLE,
93     ET_TBODY,
94     ET_SCRIPT,
95     ET_TEST,
96     ET_TESTG,
97     ET_COMMENT,
98     ET_IMG,
99     ET_TR,
100     ET_TD,
101     ET_IFRAME,
102     ET_FORM,
103     ET_FRAME
104 } elem_type_t;
105
106 static const IID * const none_iids[] = {
107     &IID_IUnknown,
108     NULL
109 };
110
111 static const IID * const doc_node_iids[] = {
112     &IID_IHTMLDOMNode,
113     &IID_IHTMLDOMNode2,
114     &IID_IHTMLDocument,
115     &IID_IHTMLDocument2,
116     &IID_IHTMLDocument3,
117     &IID_IHTMLDocument4,
118     &IID_IHTMLDocument5,
119     &IID_IDispatchEx,
120     &IID_IConnectionPointContainer,
121     &IID_IInternetHostSecurityManager,
122     NULL
123 };
124
125 static const IID * const doc_obj_iids[] = {
126     &IID_IHTMLDocument,
127     &IID_IHTMLDocument2,
128     &IID_IHTMLDocument3,
129     &IID_IHTMLDocument4,
130     &IID_IHTMLDocument5,
131     &IID_IDispatchEx,
132     &IID_IConnectionPointContainer,
133     &IID_ICustomDoc,
134     NULL
135 };
136
137 static const IID * const elem_iids[] = {
138     &IID_IHTMLDOMNode,
139     &IID_IHTMLDOMNode2,
140     &IID_IHTMLElement,
141     &IID_IHTMLElement2,
142     &IID_IHTMLElement3,
143     &IID_IDispatchEx,
144     &IID_IConnectionPointContainer,
145     NULL
146 };
147
148 static const IID * const body_iids[] = {
149     &IID_IHTMLDOMNode,
150     &IID_IHTMLDOMNode2,
151     &IID_IHTMLElement,
152     &IID_IHTMLElement2,
153     &IID_IHTMLElement3,
154     &IID_IHTMLTextContainer,
155     &IID_IHTMLBodyElement,
156     &IID_IDispatchEx,
157     &IID_IConnectionPointContainer,
158     NULL
159 };
160
161 static const IID * const anchor_iids[] = {
162     &IID_IHTMLDOMNode,
163     &IID_IHTMLDOMNode2,
164     &IID_IHTMLElement,
165     &IID_IHTMLElement2,
166     &IID_IHTMLElement3,
167     &IID_IHTMLAnchorElement,
168     &IID_IDispatchEx,
169     &IID_IConnectionPointContainer,
170     NULL
171 };
172
173 static const IID * const input_iids[] = {
174     &IID_IHTMLDOMNode,
175     &IID_IHTMLDOMNode2,
176     &IID_IHTMLElement,
177     &IID_IHTMLElement2,
178     &IID_IHTMLElement3,
179     &IID_IHTMLInputElement,
180     &IID_IHTMLInputTextElement,
181     &IID_IDispatchEx,
182     &IID_IConnectionPointContainer,
183     NULL
184 };
185
186 static const IID * const select_iids[] = {
187     &IID_IHTMLDOMNode,
188     &IID_IHTMLDOMNode2,
189     &IID_IHTMLElement,
190     &IID_IHTMLElement2,
191     &IID_IHTMLElement3,
192     &IID_IHTMLSelectElement,
193     &IID_IDispatchEx,
194     &IID_IConnectionPointContainer,
195     NULL
196 };
197
198 static const IID * const textarea_iids[] = {
199     &IID_IHTMLDOMNode,
200     &IID_IHTMLDOMNode2,
201     &IID_IHTMLElement,
202     &IID_IHTMLElement2,
203     &IID_IHTMLElement3,
204     &IID_IHTMLTextAreaElement,
205     &IID_IDispatchEx,
206     &IID_IConnectionPointContainer,
207     NULL
208 };
209
210 static const IID * const option_iids[] = {
211     &IID_IHTMLDOMNode,
212     &IID_IHTMLDOMNode2,
213     &IID_IHTMLElement,
214     &IID_IHTMLElement2,
215     &IID_IHTMLElement3,
216     &IID_IHTMLOptionElement,
217     &IID_IDispatchEx,
218     &IID_IConnectionPointContainer,
219     NULL
220 };
221
222 static const IID * const table_iids[] = {
223     &IID_IHTMLDOMNode,
224     &IID_IHTMLDOMNode2,
225     &IID_IHTMLElement,
226     &IID_IHTMLElement2,
227     &IID_IHTMLElement3,
228     &IID_IHTMLTable,
229     &IID_IDispatchEx,
230     &IID_IConnectionPointContainer,
231     NULL
232 };
233
234 static const IID * const script_iids[] = {
235     &IID_IHTMLDOMNode,
236     &IID_IHTMLDOMNode2,
237     &IID_IHTMLElement,
238     &IID_IHTMLElement2,
239     &IID_IHTMLElement3,
240     &IID_IHTMLScriptElement,
241     &IID_IDispatchEx,
242     &IID_IConnectionPointContainer,
243     NULL
244 };
245
246 static const IID * const text_iids[] = {
247     &IID_IHTMLDOMNode,
248     &IID_IHTMLDOMNode2,
249     &IID_IHTMLDOMTextNode,
250     NULL
251 };
252
253 static const IID * const location_iids[] = {
254     &IID_IDispatch,
255     &IID_IHTMLLocation,
256     NULL
257 };
258
259 static const IID * const window_iids[] = {
260     &IID_IDispatch,
261     &IID_IHTMLWindow2,
262     &IID_IHTMLWindow3,
263     &IID_IDispatchEx,
264     NULL
265 };
266
267 static const IID * const comment_iids[] = {
268     &IID_IHTMLDOMNode,
269     &IID_IHTMLDOMNode2,
270     &IID_IHTMLElement,
271     &IID_IHTMLElement2,
272     &IID_IHTMLElement3,
273     &IID_IHTMLCommentElement,
274     &IID_IDispatchEx,
275     &IID_IConnectionPointContainer,
276     NULL
277 };
278
279 static const IID * const img_iids[] = {
280     &IID_IHTMLDOMNode,
281     &IID_IHTMLDOMNode2,
282     &IID_IHTMLElement,
283     &IID_IHTMLElement2,
284     &IID_IHTMLElement3,
285     &IID_IDispatchEx,
286     &IID_IHTMLImgElement,
287     &IID_IConnectionPointContainer,
288     NULL
289 };
290
291 static const IID * const tr_iids[] = {
292     &IID_IHTMLDOMNode,
293     &IID_IHTMLDOMNode2,
294     &IID_IHTMLElement,
295     &IID_IHTMLElement2,
296     &IID_IHTMLElement3,
297     &IID_IDispatchEx,
298     &IID_IHTMLTableRow,
299     &IID_IConnectionPointContainer,
300     NULL
301 };
302
303 static const IID * const td_iids[] = {
304     &IID_IHTMLDOMNode,
305     &IID_IHTMLDOMNode2,
306     &IID_IHTMLElement,
307     &IID_IHTMLElement2,
308     &IID_IHTMLElement3,
309     &IID_IDispatchEx,
310     &IID_IConnectionPointContainer,
311     NULL
312 };
313
314 static const IID * const frame_iids[] = {
315     &IID_IHTMLDOMNode,
316     &IID_IHTMLDOMNode2,
317     &IID_IHTMLElement,
318     &IID_IHTMLElement2,
319     &IID_IHTMLElement3,
320     &IID_IHTMLFrameBase,
321     &IID_IHTMLFrameBase2,
322     &IID_IDispatchEx,
323     &IID_IConnectionPointContainer,
324     NULL
325 };
326
327 static const IID * const iframe_iids[] = {
328     &IID_IHTMLDOMNode,
329     &IID_IHTMLDOMNode2,
330     &IID_IHTMLElement,
331     &IID_IHTMLElement2,
332     &IID_IHTMLElement3,
333     &IID_IHTMLFrameBase,
334     &IID_IHTMLFrameBase2,
335     &IID_IHTMLIFrameElement,
336     &IID_IDispatchEx,
337     &IID_IConnectionPointContainer,
338     NULL
339 };
340
341 static const IID * const form_iids[] = {
342     &IID_IHTMLDOMNode,
343     &IID_IHTMLDOMNode2,
344     &IID_IHTMLElement,
345     &IID_IHTMLElement2,
346     &IID_IHTMLElement3,
347     &IID_IHTMLFormElement,
348     &IID_IDispatchEx,
349     &IID_IConnectionPointContainer,
350     NULL
351 };
352
353 static const IID * const generic_iids[] = {
354     &IID_IHTMLDOMNode,
355     &IID_IHTMLDOMNode2,
356     &IID_IHTMLElement,
357     &IID_IHTMLElement2,
358     &IID_IHTMLElement3,
359     &IID_IHTMLGenericElement,
360     &IID_IDispatchEx,
361     &IID_IConnectionPointContainer,
362     NULL
363 };
364
365 static const IID * const style_iids[] = {
366     &IID_IUnknown,
367     &IID_IDispatch,
368     &IID_IDispatchEx,
369     &IID_IHTMLStyle,
370     &IID_IHTMLStyle2,
371     &IID_IHTMLStyle3,
372     &IID_IHTMLStyle4,
373     NULL
374 };
375
376 static const IID * const cstyle_iids[] = {
377     &IID_IUnknown,
378     &IID_IDispatch,
379     &IID_IDispatchEx,
380     &IID_IHTMLCurrentStyle,
381     NULL
382 };
383
384 static const IID * const img_factory_iids[] = {
385     &IID_IUnknown,
386     &IID_IDispatch,
387     &IID_IDispatchEx,
388     &IID_IHTMLImageElementFactory,
389     NULL
390 };
391
392 typedef struct {
393     const char *tag;
394     REFIID *iids;
395     const IID *dispiid;
396 } elem_type_info_t;
397
398 static const elem_type_info_t elem_type_infos[] = {
399     {"",          none_iids,        NULL},
400     {"HTML",      elem_iids,        NULL},
401     {"HEAD",      elem_iids,        NULL},
402     {"TITLE",     elem_iids,        NULL},
403     {"BODY",      body_iids,        &DIID_DispHTMLBody},
404     {"A",         anchor_iids,      &DIID_DispHTMLAnchorElement},
405     {"INPUT",     input_iids,       &DIID_DispHTMLInputElement},
406     {"SELECT",    select_iids,      &DIID_DispHTMLSelectElement},
407     {"TEXTAREA",  textarea_iids,    NULL},
408     {"OPTION",    option_iids,      &DIID_DispHTMLOptionElement},
409     {"STYLE",     elem_iids,        NULL},
410     {"BLOCKQUOTE",elem_iids,        NULL},
411     {"P",         elem_iids,        NULL},
412     {"BR",        elem_iids,        NULL},
413     {"TABLE",     table_iids,       &DIID_DispHTMLTable},
414     {"TBODY",     elem_iids,        NULL},
415     {"SCRIPT",    script_iids,      &DIID_DispHTMLScriptElement},
416     {"TEST",      elem_iids,        &DIID_DispHTMLUnknownElement},
417     {"TEST",      generic_iids,     &DIID_DispHTMLGenericElement},
418     {"!",         comment_iids,     &DIID_DispHTMLCommentElement},
419     {"IMG",       img_iids,         &DIID_DispHTMLImg},
420     {"TR",        tr_iids,          &DIID_DispHTMLTableRow},
421     {"TD",        td_iids,          NULL},
422     {"IFRAME",    iframe_iids,      &DIID_DispHTMLIFrame},
423     {"FORM",      form_iids,        &DIID_DispHTMLFormElement},
424     {"FRAME",     frame_iids,       &DIID_DispHTMLFrameElement}
425 };
426
427 static const char *dbgstr_guid(REFIID riid)
428 {
429     static char buf[50];
430
431     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
432             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
433             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
434             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
435
436     return buf;
437 }
438
439 static int strcmp_wa(LPCWSTR strw, const char *stra)
440 {
441     CHAR buf[512];
442     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
443     return lstrcmpA(stra, buf);
444 }
445
446 static BSTR a2bstr(const char *str)
447 {
448     BSTR ret;
449     int len;
450
451     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
452     ret = SysAllocStringLen(NULL, len);
453     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
454
455     return ret;
456 }
457
458 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
459 {
460     IUnknown *unk1, *unk2;
461
462     if(iface1 == iface2)
463         return TRUE;
464
465     IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
466     IUnknown_Release(unk1);
467     IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
468     IUnknown_Release(unk2);
469
470     return unk1 == unk2;
471 }
472
473 static IHTMLDocument2 *create_document(void)
474 {
475     IHTMLDocument2 *doc;
476     IHTMLDocument5 *doc5;
477     HRESULT hres;
478
479     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
480             &IID_IHTMLDocument2, (void**)&doc);
481     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
482     if(FAILED(hres))
483         return NULL;
484
485     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
486     if(FAILED(hres)) {
487         win_skip("Could not get IHTMLDocument5, probably too old IE\n");
488         IHTMLDocument2_Release(doc);
489         return NULL;
490     }
491
492     IHTMLDocument5_Release(doc5);
493     return doc;
494 }
495
496 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
497 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
498 {
499     const IID * const *piid;
500     IUnknown *unk;
501     HRESULT hres;
502
503      for(piid = iids; *piid; piid++) {
504         hres = IDispatch_QueryInterface(iface, *piid, (void**)&unk);
505         ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", dbgstr_guid(*piid), hres);
506         if(SUCCEEDED(hres))
507             IUnknown_Release(unk);
508     }
509 }
510
511 #define test_get_dispid(u,id) _test_disp(__LINE__,u,id)
512 static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid)
513 {
514     IDispatchEx *dispex;
515     ITypeInfo *typeinfo;
516     BOOL ret = FALSE;
517     UINT ticnt;
518     HRESULT hres;
519
520     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
521     ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
522     if(FAILED(hres))
523         return FALSE;
524
525     ticnt = 0xdeadbeef;
526     hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
527     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
528     ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
529
530     hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
531     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
532
533     if(SUCCEEDED(hres)) {
534         TYPEATTR *type_attr;
535
536         hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
537         ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
538         if(hres == S_OK) {
539             *iid = type_attr->guid;
540             ret = TRUE;
541         }
542
543         ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
544         ITypeInfo_Release(typeinfo);
545     }
546
547     IDispatchEx_Release(dispex);
548     return ret;
549 }
550
551 #define test_disp_value(u) _test_disp_value(__LINE__,u,v)
552 static void _test_disp_value(unsigned line, IUnknown *unk, const char *val)
553 {
554     DISPPARAMS dp  = {NULL,NULL,0,0};
555     IDispatchEx *dispex;
556     EXCEPINFO ei;
557     VARIANT var;
558     HRESULT hres;
559
560     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
561     ok_(__FILE__,line)(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
562     if(FAILED(hres))
563         return;
564
565     hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
566     IDispatchEx_Release(dispex);
567     ok_(__FILE__,line)(hres == S_OK, "InvokeEx(DISPID_VALUE) returned: %08x\n", hres);
568
569     ok_(__FILE__,line)(V_VT(&var) == VT_BSTR, "V_VT(value) = %d\n", V_VT(&var));
570     ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&var), val), "value = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&var)), val);
571     VariantClear(&var);
572 }
573
574 #define test_disp(u,id,v) _test_disp(__LINE__,u,id,v)
575 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid, const char *val)
576 {
577     IID iid;
578
579     if(_test_get_dispid(line, unk, &iid))
580         ok_(__FILE__,line) (IsEqualGUID(&iid, diid), "unexpected guid %s\n", dbgstr_guid(&iid));
581
582     if(val)
583         _test_disp_value(line, unk, val);
584 }
585
586 #define test_disp2(u,id,id2,v) _test_disp2(__LINE__,u,id,id2,v)
587 static void _test_disp2(unsigned line, IUnknown *unk, const IID *diid, const IID *diid2, const char *val)
588 {
589     IID iid;
590
591     if(_test_get_dispid(line, unk, &iid))
592         ok_(__FILE__,line) (IsEqualGUID(&iid, diid) || broken(IsEqualGUID(&iid, diid2)),
593                 "unexpected guid %s\n", dbgstr_guid(&iid));
594
595     if(val)
596         _test_disp_value(line, unk, val);
597 }
598
599 #define get_elem_iface(u) _get_elem_iface(__LINE__,u)
600 static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk)
601 {
602     IHTMLElement *elem;
603     HRESULT hres;
604
605     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem);
606     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement: %08x\n", hres);
607     return elem;
608 }
609
610 #define get_elem2_iface(u) _get_elem2_iface(__LINE__,u)
611 static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
612 {
613     IHTMLElement2 *elem;
614     HRESULT hres;
615
616     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem);
617     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2: %08x\n", hres);
618     return elem;
619 }
620
621 #define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
622 static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
623 {
624     IHTMLElement3 *elem;
625     HRESULT hres;
626
627     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem);
628     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3: %08x\n", hres);
629     return elem;
630 }
631
632 #define get_node_iface(u) _get_node_iface(__LINE__,u)
633 static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk)
634 {
635     IHTMLDOMNode *node;
636     HRESULT hres;
637
638     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&node);
639     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode: %08x\n", hres);
640     return node;
641 }
642
643 #define get_node2_iface(u) _get_node2_iface(__LINE__,u)
644 static IHTMLDOMNode2 *_get_node2_iface(unsigned line, IUnknown *unk)
645 {
646     IHTMLDOMNode2 *node;
647     HRESULT hres;
648
649     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&node);
650     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode2: %08x\n", hres);
651     return node;
652 }
653
654 #define get_img_iface(u) _get_img_iface(__LINE__,u)
655 static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk)
656 {
657     IHTMLImgElement *img;
658     HRESULT hres;
659
660     hres = IUnknown_QueryInterface(unk, &IID_IHTMLImgElement, (void**)&img);
661     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLImgElement: %08x\n", hres);
662     return img;
663 }
664
665 #define get_anchor_iface(u) _get_anchor_iface(__LINE__,u)
666 static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk)
667 {
668     IHTMLAnchorElement *anchor;
669     HRESULT hres;
670
671     hres = IUnknown_QueryInterface(unk, &IID_IHTMLAnchorElement, (void**)&anchor);
672     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAnchorElement: %08x\n", hres);
673     return anchor;
674 }
675
676 #define get_text_iface(u) _get_text_iface(__LINE__,u)
677 static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk)
678 {
679     IHTMLDOMTextNode *text;
680     HRESULT hres;
681
682     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode, (void**)&text);
683     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode: %08x\n", hres);
684     return text;
685 }
686
687 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
688 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
689 {
690     IHTMLDOMNode *node = _get_node_iface(line, unk);
691     BSTR name;
692     HRESULT hres;
693
694     hres = IHTMLDOMNode_get_nodeName(node, &name);
695     IHTMLDOMNode_Release(node);
696     ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres);
697     ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", wine_dbgstr_w(name), exname);
698
699     SysFreeString(name);
700 }
701
702 #define get_owner_doc(u) _get_owner_doc(__LINE__,u)
703 static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk)
704 {
705     IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
706     IDispatch *disp = (void*)0xdeadbeef;
707     IHTMLDocument2 *doc = NULL;
708     HRESULT hres;
709
710     hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
711     IHTMLDOMNode2_Release(node);
712     ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
713
714     if(disp) {
715         hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
716         IDispatch_Release(disp);
717         ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
718     }
719
720     return doc;
721 }
722
723 #define get_doc_window(d) _get_doc_window(__LINE__,d)
724 static IHTMLWindow2 *_get_doc_window(unsigned line, IHTMLDocument2 *doc)
725 {
726     IHTMLWindow2 *window;
727     HRESULT hres;
728
729     window = NULL;
730     hres = IHTMLDocument2_get_parentWindow(doc, &window);
731     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
732     ok_(__FILE__,line)(window != NULL, "window == NULL\n");
733
734     return window;
735 }
736
737 #define clone_node(n,d) _clone_node(__LINE__,n,d)
738 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
739 {
740     IHTMLDOMNode *node = _get_node_iface(line, unk);
741     IHTMLDOMNode *ret = NULL;
742     HRESULT hres;
743
744     hres = IHTMLDOMNode_cloneNode(node, deep, &ret);
745     IHTMLDOMNode_Release(node);
746     ok_(__FILE__,line)(hres == S_OK, "cloneNode failed: %08x\n", hres);
747     ok_(__FILE__,line)(ret != NULL, "ret == NULL\n");
748
749     return ret;
750
751 }
752
753 #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n)
754 static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
755 {
756     IHTMLElement *elem = _get_elem_iface(line, unk);
757     BSTR tag;
758     HRESULT hres;
759
760     hres = IHTMLElement_get_tagName(elem, &tag);
761     IHTMLElement_Release(elem);
762     ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
763     ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
764
765     SysFreeString(tag);
766 }
767
768 #define test_elem_type(ifc,t) _test_elem_type(__LINE__,ifc,t)
769 static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type)
770 {
771     _test_elem_tag(line, unk, elem_type_infos[type].tag);
772     _test_ifaces(line, unk, elem_type_infos[type].iids);
773
774     if(elem_type_infos[type].dispiid && type != ET_A)
775         _test_disp(line, unk, elem_type_infos[type].dispiid, "[object]");
776 }
777
778 #define get_node_type(n) _get_node_type(__LINE__,n)
779 static LONG _get_node_type(unsigned line, IUnknown *unk)
780 {
781     IHTMLDOMNode *node = _get_node_iface(line, unk);
782     LONG type = -1;
783     HRESULT hres;
784
785     hres = IHTMLDOMNode_get_nodeType(node, &type);
786     ok(hres == S_OK, "get_nodeType failed: %08x\n", hres);
787
788     IHTMLDOMNode_Release(node);
789
790     return type;
791 }
792
793 #define get_child_nodes(u) _get_child_nodes(__LINE__,u)
794 static IHTMLDOMChildrenCollection *_get_child_nodes(unsigned line, IUnknown *unk)
795 {
796     IHTMLDOMNode *node = _get_node_iface(line, unk);
797     IHTMLDOMChildrenCollection *col = NULL;
798     IDispatch *disp;
799     HRESULT hres;
800
801     hres = IHTMLDOMNode_get_childNodes(node, &disp);
802     IHTMLDOMNode_Release(node);
803     ok_(__FILE__,line) (hres == S_OK, "get_childNodes failed: %08x\n", hres);
804     if(FAILED(hres))
805         return NULL;
806
807     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDOMChildrenCollection, (void**)&col);
808     IDispatch_Release(disp);
809     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMChildrenCollection: %08x\n", hres);
810
811     return col;
812 }
813
814 #define get_child_item(c,i) _get_child_item(__LINE__,c,i)
815 static IHTMLDOMNode *_get_child_item(unsigned line, IHTMLDOMChildrenCollection *col, LONG idx)
816 {
817     IHTMLDOMNode *node = NULL;
818     IDispatch *disp;
819     HRESULT hres;
820
821     hres = IHTMLDOMChildrenCollection_item(col, idx, &disp);
822     ok(hres == S_OK, "item failed: %08x\n", hres);
823
824     node = _get_node_iface(line, (IUnknown*)disp);
825     IDispatch_Release(disp);
826
827     return node;
828 }
829
830 #define test_elem_attr(e,n,v) _test_elem_attr(__LINE__,e,n,v)
831 static void _test_elem_attr(unsigned line, IHTMLElement *elem, const char *name, const char *exval)
832 {
833     VARIANT value;
834     BSTR tmp;
835     HRESULT hres;
836
837     VariantInit(&value);
838
839     tmp = a2bstr(name);
840     hres = IHTMLElement_getAttribute(elem, tmp, 0, &value);
841     SysFreeString(tmp);
842     ok_(__FILE__,line) (hres == S_OK, "getAttribute failed: %08x\n", hres);
843
844     if(exval) {
845         ok_(__FILE__,line) (V_VT(&value) == VT_BSTR, "vt=%d\n", V_VT(&value));
846         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&value)));
847     }else {
848         ok_(__FILE__,line) (V_VT(&value) == VT_NULL, "vt=%d\n", V_VT(&value));
849     }
850
851     VariantClear(&value);
852 }
853
854 #define test_elem_offset(u) _test_elem_offset(__LINE__,u)
855 static void _test_elem_offset(unsigned line, IUnknown *unk)
856 {
857     IHTMLElement *elem = _get_elem_iface(line, unk);
858     LONG l;
859     HRESULT hres;
860
861     hres = IHTMLElement_get_offsetTop(elem, &l);
862     ok_(__FILE__,line) (hres == S_OK, "get_offsetTop failed: %08x\n", hres);
863
864     hres = IHTMLElement_get_offsetHeight(elem, &l);
865     ok_(__FILE__,line) (hres == S_OK, "get_offsetHeight failed: %08x\n", hres);
866
867     hres = IHTMLElement_get_offsetWidth(elem, &l);
868     ok_(__FILE__,line) (hres == S_OK, "get_offsetWidth failed: %08x\n", hres);
869
870     IHTMLElement_Release(elem);
871 }
872
873 #define get_doc_node(d) _get_doc_node(__LINE__,d)
874 static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
875 {
876     IHTMLWindow2 *window;
877     IHTMLDocument2 *ret;
878     HRESULT hres;
879
880     hres = IHTMLDocument2_get_parentWindow(doc, &window);
881     ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
882
883     hres = IHTMLWindow2_get_document(window, &ret);
884     ok_(__FILE__,line)(hres == S_OK, "get_document failed: %08x\n", hres);
885     ok_(__FILE__,line)(ret != NULL, "document = NULL\n");
886
887     return ret;
888 }
889
890 #define test_window_name(d,e) _test_window_name(__LINE__,d,e)
891 static void _test_window_name(unsigned line, IHTMLWindow2 *window, const char *exname)
892 {
893     BSTR name;
894     HRESULT hres;
895
896     hres = IHTMLWindow2_get_name(window, &name);
897     ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
898     if(exname)
899         ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s\n", wine_dbgstr_w(name));
900     else
901         ok_(__FILE__,line)(!name, "name = %s\n", wine_dbgstr_w(name));
902 }
903
904 #define set_window_name(w,n) _set_window_name(__LINE__,w,n)
905 static void _set_window_name(unsigned line, IHTMLWindow2 *window, const char *name)
906 {
907     BSTR str;
908     HRESULT hres;
909
910     str = a2bstr(name);
911     hres = IHTMLWindow2_put_name(window, str);
912     SysFreeString(str);
913     ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
914
915     _test_window_name(line, window, name);
916 }
917
918 #define test_window_length(w,l) _test_window_length(__LINE__,w,l)
919 static void _test_window_length(unsigned line, IHTMLWindow2 *window, LONG exlen)
920 {
921     LONG length = -1;
922     HRESULT hres;
923
924     hres = IHTMLWindow2_get_length(window, &length);
925     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
926     ok_(__FILE__,line)(length == exlen, "length = %d, expected %d\n", length, exlen);
927 }
928
929 #define get_frame_content_window(e) _get_frame_content_window(__LINE__,e)
930 static IHTMLWindow2 *_get_frame_content_window(unsigned line, IUnknown *elem)
931 {
932     IHTMLFrameBase2 *base2;
933     IHTMLWindow2 *window;
934     HRESULT hres;
935
936     hres = IUnknown_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
937     ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
938
939     window = NULL;
940     hres = IHTMLFrameBase2_get_contentWindow(base2, &window);
941     IHTMLFrameBase2_Release(base2);
942     ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
943     ok(window != NULL, "contentWindow = NULL\n");
944
945     return window;
946 }
947
948 static void test_get_set_attr(IHTMLDocument2 *doc)
949 {
950     IHTMLElement *elem;
951     IHTMLDocument3 *doc3;
952     HRESULT hres;
953     BSTR bstr;
954     VARIANT val;
955
956     /* grab an element to test with */
957     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
958     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
959
960     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
961     IHTMLDocument3_Release(doc3);
962     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
963
964     /* get a non-present attribute */
965     bstr = a2bstr("notAnAttribute");
966     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
967     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
968     ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val));
969     VariantClear(&val);
970     SysFreeString(bstr);
971
972     /* get a present attribute */
973     bstr = a2bstr("scrollHeight");
974     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
975     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
976     ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val));
977     VariantClear(&val);
978     SysFreeString(bstr);
979
980     /* create a new BSTR attribute */
981     bstr = a2bstr("newAttribute");
982
983     V_VT(&val) = VT_BSTR;
984     V_BSTR(&val) = a2bstr("the value");
985     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
986     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
987     VariantClear(&val);
988
989     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
990     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
991     ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val));
992     ok(strcmp_wa(V_BSTR(&val), "the value") == 0, "variant value should have been L\"the value\", was %s\n", wine_dbgstr_w(V_BSTR(&val)));
993     VariantClear(&val);
994
995     /* overwrite the attribute with a BOOL */
996     V_VT(&val) = VT_BOOL;
997     V_BOOL(&val) = VARIANT_TRUE;
998     hres = IHTMLElement_setAttribute(elem, bstr, val, 0);
999     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
1000     VariantClear(&val);
1001
1002     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1003     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1004     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1005     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1006     VariantClear(&val);
1007
1008     SysFreeString(bstr);
1009
1010     /* case-insensitive */
1011     bstr = a2bstr("newattribute");
1012     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
1013     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
1014     ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
1015     ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
1016     VariantClear(&val);
1017     SysFreeString(bstr);
1018
1019     IHTMLElement_Release(elem);
1020 }
1021
1022 #define get_doc_elem(d) _get_doc_elem(__LINE__,d)
1023 static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc)
1024 {
1025     IHTMLElement *elem;
1026     IHTMLDocument3 *doc3;
1027     HRESULT hres;
1028
1029     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1030     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
1031     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
1032     ok_(__FILE__,line) (hres == S_OK, "get_documentElement failed: %08x\n", hres);
1033     IHTMLDocument3_Release(doc3);
1034
1035     return elem;
1036 }
1037
1038 #define test_anchor_href(a,h) _test_anchor_href(__LINE__,a,h)
1039 static void _test_anchor_href(unsigned line, IUnknown *unk, const char *exhref)
1040 {
1041     IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk);
1042     BSTR str;
1043     HRESULT hres;
1044
1045     hres = IHTMLAnchorElement_get_href(anchor, &str);
1046     ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres);
1047     ok_(__FILE__,line)(!strcmp_wa(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), exhref);
1048     SysFreeString(str);
1049
1050     _test_disp_value(line, unk, exhref);
1051 }
1052
1053 #define test_option_text(o,t) _test_option_text(__LINE__,o,t)
1054 static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text)
1055 {
1056     BSTR bstr;
1057     HRESULT hres;
1058
1059     hres = IHTMLOptionElement_get_text(option, &bstr);
1060     ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres);
1061     ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", wine_dbgstr_w(bstr));
1062     SysFreeString(bstr);
1063 }
1064
1065 #define test_option_put_text(o,t) _test_option_put_text(__LINE__,o,t)
1066 static void _test_option_put_text(unsigned line, IHTMLOptionElement *option, const char *text)
1067 {
1068     BSTR bstr;
1069     HRESULT hres;
1070
1071     bstr = a2bstr(text);
1072     hres = IHTMLOptionElement_put_text(option, bstr);
1073     SysFreeString(bstr);
1074     ok(hres == S_OK, "put_text failed: %08x\n", hres);
1075
1076     _test_option_text(line, option, text);
1077 }
1078
1079 #define test_option_value(o,t) _test_option_value(__LINE__,o,t)
1080 static void _test_option_value(unsigned line, IHTMLOptionElement *option, const char *value)
1081 {
1082     BSTR bstr;
1083     HRESULT hres;
1084
1085     hres = IHTMLOptionElement_get_value(option, &bstr);
1086     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1087     ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", wine_dbgstr_w(bstr));
1088     SysFreeString(bstr);
1089 }
1090
1091 #define test_option_put_value(o,t) _test_option_put_value(__LINE__,o,t)
1092 static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, const char *value)
1093 {
1094     BSTR bstr;
1095     HRESULT hres;
1096
1097     bstr = a2bstr(value);
1098     hres = IHTMLOptionElement_put_value(option, bstr);
1099     SysFreeString(bstr);
1100     ok(hres == S_OK, "put_value failed: %08x\n", hres);
1101
1102     _test_option_value(line, option, value);
1103 }
1104
1105 #define create_option_elem(d,t,v) _create_option_elem(__LINE__,d,t,v)
1106 static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *doc,
1107         const char *txt, const char *val)
1108 {
1109     IHTMLOptionElementFactory *factory;
1110     IHTMLOptionElement *option;
1111     IHTMLWindow2 *window;
1112     VARIANT text, value, empty;
1113     HRESULT hres;
1114
1115     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1116     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1117
1118     hres = IHTMLWindow2_get_Option(window, &factory);
1119     IHTMLWindow2_Release(window);
1120     ok_(__FILE__,line) (hres == S_OK, "get_Option failed: %08x\n", hres);
1121
1122     V_VT(&text) = VT_BSTR;
1123     V_BSTR(&text) = a2bstr(txt);
1124     V_VT(&value) = VT_BSTR;
1125     V_BSTR(&value) = a2bstr(val);
1126     V_VT(&empty) = VT_EMPTY;
1127
1128     hres = IHTMLOptionElementFactory_create(factory, text, value, empty, empty, &option);
1129     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1130
1131     IHTMLOptionElementFactory_Release(factory);
1132     VariantClear(&text);
1133     VariantClear(&value);
1134
1135     _test_option_text(line, option, txt);
1136     _test_option_value(line, option, val);
1137
1138     return option;
1139 }
1140
1141 #define test_img_width(o,w) _test_img_width(__LINE__,o,w)
1142 static void _test_img_width(unsigned line, IHTMLImgElement *img, const long exp)
1143 {
1144     LONG found = -1;
1145     HRESULT hres;
1146
1147     hres = IHTMLImgElement_get_width(img, &found);
1148     todo_wine ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
1149     todo_wine ok_(__FILE__,line) (found == exp, "width=%d\n", found);
1150 }
1151
1152 #define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
1153 static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const long width)
1154 {
1155     HRESULT hres;
1156
1157     hres = IHTMLImgElement_put_width(img, width);
1158     todo_wine ok(hres == S_OK, "put_width failed: %08x\n", hres);
1159
1160     _test_img_width(line, img, width);
1161 }
1162
1163 #define test_img_height(o,h) _test_img_height(__LINE__,o,h)
1164 static void _test_img_height(unsigned line, IHTMLImgElement *img, const long exp)
1165 {
1166     LONG found = -1;
1167     HRESULT hres;
1168
1169     hres = IHTMLImgElement_get_height(img, &found);
1170     todo_wine ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
1171     todo_wine ok_(__FILE__,line) (found == exp, "height=%d\n", found);
1172 }
1173
1174 #define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
1175 static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const long height)
1176 {
1177     HRESULT hres;
1178
1179     hres = IHTMLImgElement_put_height(img, height);
1180     todo_wine ok(hres == S_OK, "put_height failed: %08x\n", hres);
1181
1182     _test_img_height(line, img, height);
1183 }
1184
1185 #define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
1186 static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
1187         LONG wdth, LONG hght)
1188 {
1189     IHTMLImageElementFactory *factory;
1190     IHTMLImgElement *img;
1191     IHTMLWindow2 *window;
1192     VARIANT width, height;
1193     char buf[16];
1194     HRESULT hres;
1195
1196     hres = IHTMLDocument2_get_parentWindow(doc, &window);
1197     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1198
1199     hres = IHTMLWindow2_get_Image(window, &factory);
1200     IHTMLWindow2_Release(window);
1201     ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
1202
1203     test_ifaces((IUnknown*)factory, img_factory_iids);
1204     test_disp((IUnknown*)factory, &IID_IHTMLImageElementFactory, "[object]");
1205
1206     if(wdth >= 0){
1207         snprintf(buf, 16, "%d", wdth);
1208         V_VT(&width) = VT_BSTR;
1209         V_BSTR(&width) = a2bstr(buf);
1210     }else{
1211         V_VT(&width) = VT_EMPTY;
1212         wdth = 0;
1213     }
1214
1215     if(hght >= 0){
1216         snprintf(buf, 16, "%d", hght);
1217         V_VT(&height) = VT_BSTR;
1218         V_BSTR(&height) = a2bstr(buf);
1219     }else{
1220         V_VT(&height) = VT_EMPTY;
1221         hght = 0;
1222     }
1223
1224     hres = IHTMLImageElementFactory_create(factory, width, height, &img);
1225     ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
1226
1227     IHTMLImageElementFactory_Release(factory);
1228     VariantClear(&width);
1229     VariantClear(&height);
1230
1231     if(SUCCEEDED(hres)) {
1232         _test_img_width(line, img, wdth);
1233         _test_img_height(line, img, hght);
1234         return img;
1235     }
1236
1237     return NULL;
1238 }
1239
1240 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
1241 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
1242 {
1243     LONG len = 0xdeadbeef;
1244     HRESULT hres;
1245
1246     hres = IHTMLSelectElement_get_length(select, &len);
1247     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1248     ok_(__FILE__,line) (len == length, "len=%d, expected %d\n", len, length);
1249 }
1250
1251 #define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i)
1252 static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1253 {
1254     LONG idx = 0xdeadbeef;
1255     HRESULT hres;
1256
1257     hres = IHTMLSelectElement_get_selectedIndex(select, &idx);
1258     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1259     ok_(__FILE__,line) (idx == index, "idx=%d, expected %d\n", idx, index);
1260 }
1261
1262 #define test_select_put_selidx(s,i) _test_select_put_selidx(__LINE__,s,i)
1263 static void _test_select_put_selidx(unsigned line, IHTMLSelectElement *select, LONG index)
1264 {
1265     HRESULT hres;
1266
1267     hres = IHTMLSelectElement_put_selectedIndex(select, index);
1268     ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres);
1269     _test_select_selidx(line, select, index);
1270 }
1271
1272 #define test_select_value(s,v) _test_select_value(__LINE__,s,v)
1273 static void _test_select_value(unsigned line, IHTMLSelectElement *select, const char *exval)
1274 {
1275     BSTR val;
1276     HRESULT hres;
1277
1278     hres = IHTMLSelectElement_get_value(select, &val);
1279     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
1280     if(exval)
1281         ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", wine_dbgstr_w(val));
1282     else
1283         ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", wine_dbgstr_w(val));
1284 }
1285
1286 #define test_select_set_value(s,v) _test_select_set_value(__LINE__,s,v)
1287 static void _test_select_set_value(unsigned line, IHTMLSelectElement *select, const char *val)
1288 {
1289     BSTR bstr;
1290     HRESULT hres;
1291
1292     bstr = a2bstr(val);
1293     hres = IHTMLSelectElement_put_value(select, bstr);
1294     SysFreeString(bstr);
1295     ok_(__FILE__,line) (hres == S_OK, "put_value failed: %08x\n", hres);
1296 }
1297
1298 #define test_select_type(s,t) _test_select_type(__LINE__,s,t)
1299 static void _test_select_type(unsigned line, IHTMLSelectElement *select, const char *extype)
1300 {
1301     BSTR type;
1302     HRESULT hres;
1303
1304     hres = IHTMLSelectElement_get_type(select, &type);
1305     ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres);
1306     ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype);
1307 }
1308
1309 #define test_range_text(r,t) _test_range_text(__LINE__,r,t)
1310 static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *extext)
1311 {
1312     BSTR text;
1313     HRESULT hres;
1314
1315     hres = IHTMLTxtRange_get_text(range, &text);
1316     ok_(__FILE__, line) (hres == S_OK, "get_text failed: %08x\n", hres);
1317
1318     if(extext) {
1319         ok_(__FILE__, line) (text != NULL, "text == NULL\n");
1320         ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=%s, expected %s\n", wine_dbgstr_w(text), extext);
1321     }else {
1322         ok_(__FILE__, line) (text == NULL, "text=%s, expected NULL\n", wine_dbgstr_w(text));
1323     }
1324
1325     SysFreeString(text);
1326
1327 }
1328
1329 #define test_range_collapse(r,b) _test_range_collapse(__LINE__,r,b)
1330 static void _test_range_collapse(unsigned line, IHTMLTxtRange *range, BOOL b)
1331 {
1332     HRESULT hres;
1333
1334     hres = IHTMLTxtRange_collapse(range, b);
1335     ok_(__FILE__, line) (hres == S_OK, "collapse failed: %08x\n", hres);
1336     _test_range_text(line, range, NULL);
1337 }
1338
1339 #define test_range_expand(r,u,b,t) _test_range_expand(__LINE__,r,u,b,t)
1340 static void _test_range_expand(unsigned line, IHTMLTxtRange *range, LPWSTR unit,
1341         VARIANT_BOOL exb, const char *extext)
1342 {
1343     VARIANT_BOOL b = 0xe0e0;
1344     HRESULT hres;
1345
1346     hres = IHTMLTxtRange_expand(range, unit, &b);
1347     ok_(__FILE__,line) (hres == S_OK, "expand failed: %08x\n", hres);
1348     ok_(__FILE__,line) (b == exb, "b=%x, expected %x\n", b, exb);
1349     _test_range_text(line, range, extext);
1350 }
1351
1352 #define test_range_move(r,u,c,e) _test_range_move(__LINE__,r,u,c,e)
1353 static void _test_range_move(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1354 {
1355     LONG c = 0xdeadbeef;
1356     HRESULT hres;
1357
1358     hres = IHTMLTxtRange_move(range, unit, cnt, &c);
1359     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1360     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1361     _test_range_text(line, range, NULL);
1362 }
1363
1364 #define test_range_movestart(r,u,c,e) _test_range_movestart(__LINE__,r,u,c,e)
1365 static void _test_range_movestart(unsigned line, IHTMLTxtRange *range,
1366         LPWSTR unit, LONG cnt, LONG excnt)
1367 {
1368     LONG c = 0xdeadbeef;
1369     HRESULT hres;
1370
1371     hres = IHTMLTxtRange_moveStart(range, unit, cnt, &c);
1372     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1373     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1374 }
1375
1376 #define test_range_moveend(r,u,c,e) _test_range_moveend(__LINE__,r,u,c,e)
1377 static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit, LONG cnt, LONG excnt)
1378 {
1379     LONG c = 0xdeadbeef;
1380     HRESULT hres;
1381
1382     hres = IHTMLTxtRange_moveEnd(range, unit, cnt, &c);
1383     ok_(__FILE__,line) (hres == S_OK, "move failed: %08x\n", hres);
1384     ok_(__FILE__,line) (c == excnt, "count=%d, expected %d\n", c, excnt);
1385 }
1386
1387 #define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t)
1388 static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, const char *text)
1389 {
1390     HRESULT hres;
1391     BSTR bstr = a2bstr(text);
1392
1393     hres = IHTMLTxtRange_put_text(range, bstr);
1394     ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres);
1395     SysFreeString(bstr);
1396     _test_range_text(line, range, NULL);
1397 }
1398
1399 #define test_range_inrange(r1,r2,b) _test_range_inrange(__LINE__,r1,r2,b)
1400 static void _test_range_inrange(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1401 {
1402     VARIANT_BOOL b;
1403     HRESULT hres;
1404
1405     b = 0xe0e0;
1406     hres = IHTMLTxtRange_inRange(range1, range2, &b);
1407     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
1408     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
1409 }
1410
1411 #define test_range_isequal(r1,r2,b) _test_range_isequal(__LINE__,r1,r2,b)
1412 static void _test_range_isequal(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRange *range2, VARIANT_BOOL exb)
1413 {
1414     VARIANT_BOOL b;
1415     HRESULT hres;
1416
1417     b = 0xe0e0;
1418     hres = IHTMLTxtRange_isEqual(range1, range2, &b);
1419     ok_(__FILE__,line) (hres == S_OK, "(1->2) isEqual failed: %08x\n", hres);
1420     ok_(__FILE__,line) (b == exb, "(1->2) b=%x, expected %x\n", b, exb);
1421
1422     b = 0xe0e0;
1423     hres = IHTMLTxtRange_isEqual(range2, range1, &b);
1424     ok_(__FILE__,line) (hres == S_OK, "(2->1) isEqual failed: %08x\n", hres);
1425     ok_(__FILE__,line) (b == exb, "(2->1) b=%x, expected %x\n", b, exb);
1426
1427     if(exb) {
1428         test_range_inrange(range1, range2, VARIANT_TRUE);
1429         test_range_inrange(range2, range1, VARIANT_TRUE);
1430     }
1431 }
1432
1433 #define test_range_parent(r,t) _test_range_parent(__LINE__,r,t)
1434 static void _test_range_parent(unsigned line, IHTMLTxtRange *range, elem_type_t type)
1435 {
1436     IHTMLElement *elem;
1437     HRESULT hres;
1438
1439     hres = IHTMLTxtRange_parentElement(range, &elem);
1440     ok_(__FILE__,line) (hres == S_OK, "parentElement failed: %08x\n", hres);
1441
1442     _test_elem_type(line, (IUnknown*)elem, type);
1443
1444     IHTMLElement_Release(elem);
1445 }
1446
1447 #define test_elem_collection(c,t,l) _test_elem_collection(__LINE__,c,t,l)
1448 static void _test_elem_collection(unsigned line, IUnknown *unk,
1449         const elem_type_t *elem_types, LONG exlen)
1450 {
1451     IHTMLElementCollection *col;
1452     LONG len;
1453     DWORD i;
1454     VARIANT name, index;
1455     IDispatch *disp, *disp2;
1456     HRESULT hres;
1457
1458     hres = IUnknown_QueryInterface(unk, &IID_IHTMLElementCollection, (void**)&col);
1459     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres);
1460
1461     test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection, "[object]");
1462
1463     hres = IHTMLElementCollection_get_length(col, &len);
1464     ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
1465     ok_(__FILE__,line) (len == exlen, "len=%d, expected %d\n", len, exlen);
1466
1467     if(len > exlen)
1468         len = exlen;
1469
1470     V_VT(&index) = VT_EMPTY;
1471
1472     for(i=0; i<len; i++) {
1473         V_VT(&name) = VT_I4;
1474         V_I4(&name) = i;
1475         disp = (void*)0xdeadbeef;
1476         hres = IHTMLElementCollection_item(col, name, index, &disp);
1477         ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
1478         ok_(__FILE__,line) (disp != NULL, "item returned NULL\n");
1479         if(FAILED(hres) || !disp)
1480             continue;
1481
1482         _test_elem_type(line, (IUnknown*)disp, elem_types[i]);
1483
1484         if(!i) {
1485             V_VT(&name) = VT_UINT;
1486             V_I4(&name) = 0;
1487             disp2 = (void*)0xdeadbeef;
1488             hres = IHTMLElementCollection_item(col, name, index, &disp2);
1489             ok_(__FILE__,line) (hres == S_OK, "item(%d) failed: %08x\n", i, hres);
1490             ok_(__FILE__,line) (iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
1491             if(disp2)
1492                 IDispatch_Release(disp2);
1493         }
1494
1495         IDispatch_Release(disp);
1496     }
1497
1498     V_VT(&name) = VT_I4;
1499     V_I4(&name) = len;
1500     disp = (void*)0xdeadbeef;
1501     hres = IHTMLElementCollection_item(col, name, index, &disp);
1502     ok_(__FILE__,line) (hres == S_OK, "item failed: %08x\n", hres);
1503     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
1504
1505     V_VT(&name) = VT_I4;
1506     V_I4(&name) = -1;
1507     disp = (void*)0xdeadbeef;
1508     hres = IHTMLElementCollection_item(col, name, index, &disp);
1509     ok_(__FILE__,line) (hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
1510     ok_(__FILE__,line) (disp == NULL, "disp != NULL\n");
1511
1512     IHTMLElementCollection_Release(col);
1513 }
1514
1515 #define test_elem_all(c,t,l) _test_elem_all(__LINE__,c,t,l)
1516 static void _test_elem_all(unsigned line, IUnknown *unk, const elem_type_t *elem_types, LONG exlen)
1517 {
1518     IHTMLElement *elem = _get_elem_iface(line, unk);
1519     IDispatch *disp;
1520     HRESULT hres;
1521
1522     hres = IHTMLElement_get_all(elem, &disp);
1523     IHTMLElement_Release(elem);
1524     ok_(__FILE__,line)(hres == S_OK, "get_all failed: %08x\n", hres);
1525
1526     _test_elem_collection(line, (IUnknown*)disp, elem_types, exlen);
1527     IDispatch_Release(disp);
1528 }
1529
1530 #define test_elem_getelembytag(u,t,l) _test_elem_getelembytag(__LINE__,u,t,l)
1531 static void _test_elem_getelembytag(unsigned line, IUnknown *unk, elem_type_t type, LONG exlen)
1532 {
1533     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1534     IHTMLElementCollection *col = NULL;
1535     elem_type_t *types = NULL;
1536     BSTR tmp;
1537     int i;
1538     HRESULT hres;
1539
1540     tmp = a2bstr(elem_type_infos[type].tag);
1541     hres = IHTMLElement2_getElementsByTagName(elem, tmp, &col);
1542     SysFreeString(tmp);
1543     IHTMLElement2_Release(elem);
1544     ok_(__FILE__,line) (hres == S_OK, "getElementByTagName failed: %08x\n", hres);
1545     ok_(__FILE__,line) (col != NULL, "col == NULL\n");
1546
1547     if(exlen) {
1548         types = HeapAlloc(GetProcessHeap(), 0, exlen*sizeof(elem_type_t));
1549         for(i=0; i<exlen; i++)
1550             types[i] = type;
1551     }
1552
1553     _test_elem_collection(line, (IUnknown*)col, types, exlen);
1554
1555     HeapFree(GetProcessHeap(), 0, types);
1556 }
1557
1558 #define test_elem_innertext(e,t) _test_elem_innertext(__LINE__,e,t)
1559 static void _test_elem_innertext(unsigned line, IHTMLElement *elem, const char *extext)
1560 {
1561     BSTR text = NULL;
1562     HRESULT hres;
1563
1564     hres = IHTMLElement_get_innerText(elem, &text);
1565     ok_(__FILE__,line) (hres == S_OK, "get_innerText failed: %08x\n", hres);
1566     ok_(__FILE__,line) (!strcmp_wa(text, extext), "get_innerText returned %s expected %s\n",
1567                         wine_dbgstr_w(text), extext);
1568     SysFreeString(text);
1569 }
1570
1571 #define test_elem_set_innertext(e,t) _test_elem_set_innertext(__LINE__,e,t)
1572 static void _test_elem_set_innertext(unsigned line, IHTMLElement *elem, const char *text)
1573 {
1574     IHTMLDOMChildrenCollection *col;
1575     BSTR str;
1576     HRESULT hres;
1577
1578     str = a2bstr(text);
1579     hres = IHTMLElement_put_innerText(elem, str);
1580     ok_(__FILE__,line) (hres == S_OK, "put_innerText failed: %08x\n", hres);
1581     SysFreeString(str);
1582
1583     _test_elem_innertext(line, elem, text);
1584
1585
1586     col = _get_child_nodes(line, (IUnknown*)elem);
1587     ok(col != NULL, "col == NULL\n");
1588     if(col) {
1589         LONG length = 0, type;
1590         IHTMLDOMNode *node;
1591
1592         hres = IHTMLDOMChildrenCollection_get_length(col, &length);
1593         ok(hres == S_OK, "get_length failed: %08x\n", hres);
1594         ok(length == 1, "length = %d\n", length);
1595
1596         node = _get_child_item(line, col, 0);
1597         ok(node != NULL, "node == NULL\n");
1598         if(node) {
1599             type = _get_node_type(line, (IUnknown*)node);
1600             ok(type == 3, "type=%d\n", type);
1601             IHTMLDOMNode_Release(node);
1602         }
1603
1604         IHTMLDOMChildrenCollection_Release(col);
1605     }
1606
1607 }
1608
1609 #define test_elem_innerhtml(e,t) _test_elem_innerhtml(__LINE__,e,t)
1610 static void _test_elem_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
1611 {
1612     IHTMLElement *elem = _get_elem_iface(line, unk);
1613     BSTR html;
1614     HRESULT hres;
1615
1616     hres = IHTMLElement_get_innerHTML(elem, &html);
1617     ok_(__FILE__,line)(hres == S_OK, "get_innerHTML failed: %08x\n", hres);
1618     if(inner_html)
1619         ok_(__FILE__,line)(!strcmp_wa(html, inner_html), "unexpected innerHTML: %s\n", wine_dbgstr_w(html));
1620     else
1621         ok_(__FILE__,line)(!html, "innerHTML = %s\n", wine_dbgstr_w(html));
1622
1623     IHTMLElement_Release(elem);
1624     SysFreeString(html);
1625 }
1626
1627 #define test_elem_set_innerhtml(e,t) _test_elem_set_innerhtml(__LINE__,e,t)
1628 static void _test_elem_set_innerhtml(unsigned line, IUnknown *unk, const char *inner_html)
1629 {
1630     IHTMLElement *elem = _get_elem_iface(line, unk);
1631     BSTR html;
1632     HRESULT hres;
1633
1634     html = a2bstr(inner_html);
1635     hres = IHTMLElement_put_innerHTML(elem, html);
1636     ok_(__FILE__,line)(hres == S_OK, "put_innerHTML failed: %08x\n", hres);
1637
1638     IHTMLElement_Release(elem);
1639     SysFreeString(html);
1640 }
1641
1642 #define test_elem_set_outerhtml(e,t) _test_elem_set_outerhtml(__LINE__,e,t)
1643 static void _test_elem_set_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
1644 {
1645     IHTMLElement *elem = _get_elem_iface(line, unk);
1646     BSTR html;
1647     HRESULT hres;
1648
1649     html = a2bstr(outer_html);
1650     hres = IHTMLElement_put_outerHTML(elem, html);
1651     ok_(__FILE__,line)(hres == S_OK, "put_outerHTML failed: %08x\n", hres);
1652
1653     IHTMLElement_Release(elem);
1654     SysFreeString(html);
1655 }
1656
1657 #define get_first_child(n) _get_first_child(__LINE__,n)
1658 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
1659 {
1660     IHTMLDOMNode *node = _get_node_iface(line, unk);
1661     IHTMLDOMNode *child = NULL;
1662     HRESULT hres;
1663
1664     hres = IHTMLDOMNode_get_firstChild(node, &child);
1665     IHTMLDOMNode_Release(node);
1666     ok_(__FILE__,line) (hres == S_OK, "get_firstChild failed: %08x\n", hres);
1667
1668     return child;
1669 }
1670
1671 #define test_node_has_child(u,b) _test_node_has_child(__LINE__,u,b)
1672 static void _test_node_has_child(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
1673 {
1674     IHTMLDOMNode *node = _get_node_iface(line, unk);
1675     VARIANT_BOOL b = 0xdead;
1676     HRESULT hres;
1677
1678     hres = IHTMLDOMNode_hasChildNodes(node, &b);
1679     ok_(__FILE__,line) (hres == S_OK, "hasChildNodes failed: %08x\n", hres);
1680     ok_(__FILE__,line) (b == exb, "hasChildNodes=%x, expected %x\n", b, exb);
1681
1682     IHTMLDOMNode_Release(node);
1683 }
1684
1685 #define test_node_get_parent(u) _test_node_get_parent(__LINE__,u)
1686 static IHTMLDOMNode *_test_node_get_parent(unsigned line, IUnknown *unk)
1687 {
1688     IHTMLDOMNode *node = _get_node_iface(line, unk);
1689     IHTMLDOMNode *parent;
1690     HRESULT hres;
1691
1692     hres = IHTMLDOMNode_get_parentNode(node, &parent);
1693     IHTMLDOMNode_Release(node);
1694     ok_(__FILE__,line) (hres == S_OK, "get_parentNode failed: %08x\n", hres);
1695
1696     return parent;
1697 }
1698
1699 #define node_get_next(u) _node_get_next(__LINE__,u)
1700 static IHTMLDOMNode *_node_get_next(unsigned line, IUnknown *unk)
1701 {
1702     IHTMLDOMNode *node = _get_node_iface(line, unk);
1703     IHTMLDOMNode *next;
1704     HRESULT hres;
1705
1706     hres = IHTMLDOMNode_get_nextSibling(node, &next);
1707     IHTMLDOMNode_Release(node);
1708     ok_(__FILE__,line) (hres == S_OK, "get_nextSiblibg failed: %08x\n", hres);
1709
1710     return next;
1711 }
1712
1713 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
1714 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
1715 {
1716     IHTMLElement *elem = _get_elem_iface(line, unk);
1717     IHTMLElement *parent;
1718     HRESULT hres;
1719
1720     hres = IHTMLElement_get_parentElement(elem, &parent);
1721     IHTMLElement_Release(elem);
1722     ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
1723
1724     return parent;
1725 }
1726
1727 #define test_elem3_get_disabled(i,b) _test_elem3_get_disabled(__LINE__,i,b)
1728 static void _test_elem3_get_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL exb)
1729 {
1730     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
1731     VARIANT_BOOL disabled = 100;
1732     HRESULT hres;
1733
1734     if (!elem3) return;
1735     hres = IHTMLElement3_get_disabled(elem3, &disabled);
1736     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1737     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
1738     IHTMLElement3_Release(elem3);
1739 }
1740
1741 #define test_elem3_set_disabled(i,b) _test_elem3_set_disabled(__LINE__,i,b)
1742 static void _test_elem3_set_disabled(unsigned line, IUnknown *unk, VARIANT_BOOL b)
1743 {
1744     IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
1745     HRESULT hres;
1746
1747     if (!elem3) return;
1748     hres = IHTMLElement3_put_disabled(elem3, b);
1749     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1750
1751     IHTMLElement3_Release(elem3);
1752     _test_elem3_get_disabled(line, unk, b);
1753 }
1754
1755 #define test_select_get_disabled(i,b) _test_select_get_disabled(__LINE__,i,b)
1756 static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL exb)
1757 {
1758     VARIANT_BOOL disabled = 100;
1759     HRESULT hres;
1760
1761     hres = IHTMLSelectElement_get_disabled(select, &disabled);
1762     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1763     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
1764
1765     _test_elem3_get_disabled(line, (IUnknown*)select, exb);
1766 }
1767
1768 #define test_text_length(u,l) _test_text_length(__LINE__,u,l)
1769 static void _test_text_length(unsigned line, IUnknown *unk, LONG l)
1770 {
1771     IHTMLDOMTextNode *text = _get_text_iface(line, unk);
1772     LONG length;
1773     HRESULT hres;
1774
1775     hres = IHTMLDOMTextNode_get_length(text, &length);
1776     ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
1777     ok_(__FILE__,line)(length == l, "length = %d, expected %d\n", length, l);
1778     IHTMLDOMTextNode_Release(text);
1779 }
1780
1781 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
1782 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
1783 {
1784     HRESULT hres;
1785
1786     hres = IHTMLSelectElement_put_disabled(select, b);
1787     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1788
1789     _test_select_get_disabled(line, select, b);
1790 }
1791
1792 #define elem_get_scroll_height(u) _elem_get_scroll_height(__LINE__,u)
1793 static LONG _elem_get_scroll_height(unsigned line, IUnknown *unk)
1794 {
1795     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1796     IHTMLTextContainer *txtcont;
1797     LONG l = -1, l2 = -1;
1798     HRESULT hres;
1799
1800     hres = IHTMLElement2_get_scrollHeight(elem, &l);
1801     ok_(__FILE__,line) (hres == S_OK, "get_scrollHeight failed: %08x\n", hres);
1802     IHTMLElement2_Release(elem);
1803
1804     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1805     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1806
1807     hres = IHTMLTextContainer_get_scrollHeight(txtcont, &l2);
1808     IHTMLTextContainer_Release(txtcont);
1809     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollHeight failed: %d\n", l2);
1810     ok_(__FILE__,line) (l == l2, "unexpected height %d, expected %d\n", l2, l);
1811
1812     return l;
1813 }
1814
1815 #define elem_get_scroll_width(u) _elem_get_scroll_width(__LINE__,u)
1816 static LONG _elem_get_scroll_width(unsigned line, IUnknown *unk)
1817 {
1818     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1819     IHTMLTextContainer *txtcont;
1820     LONG l = -1, l2 = -1;
1821     HRESULT hres;
1822
1823     hres = IHTMLElement2_get_scrollWidth(elem, &l);
1824     ok_(__FILE__,line) (hres == S_OK, "get_scrollWidth failed: %08x\n", hres);
1825     IHTMLElement2_Release(elem);
1826
1827     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1828     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1829
1830     hres = IHTMLTextContainer_get_scrollWidth(txtcont, &l2);
1831     IHTMLTextContainer_Release(txtcont);
1832     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollWidth failed: %d\n", l2);
1833     ok_(__FILE__,line) (l == l2, "unexpected width %d, expected %d\n", l2, l);
1834
1835     return l;
1836 }
1837
1838 #define elem_get_scroll_top(u) _elem_get_scroll_top(__LINE__,u)
1839 static LONG _elem_get_scroll_top(unsigned line, IUnknown *unk)
1840 {
1841     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1842     IHTMLTextContainer *txtcont;
1843     LONG l = -1, l2 = -1;
1844     HRESULT hres;
1845
1846     hres = IHTMLElement2_get_scrollTop(elem, &l);
1847     ok_(__FILE__,line) (hres == S_OK, "get_scrollTop failed: %08x\n", hres);
1848     IHTMLElement2_Release(elem);
1849
1850     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1851     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1852
1853     hres = IHTMLTextContainer_get_scrollTop(txtcont, &l2);
1854     IHTMLTextContainer_Release(txtcont);
1855     ok_(__FILE__,line) (hres == S_OK, "IHTMLTextContainer::get_scrollTop failed: %d\n", l2);
1856     ok_(__FILE__,line) (l == l2, "unexpected top %d, expected %d\n", l2, l);
1857
1858     return l;
1859 }
1860
1861 #define elem_get_scroll_left(u) _elem_get_scroll_left(__LINE__,u)
1862 static void _elem_get_scroll_left(unsigned line, IUnknown *unk)
1863 {
1864     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
1865     IHTMLTextContainer *txtcont;
1866     LONG l = -1, l2 = -1;
1867     HRESULT hres;
1868
1869     hres = IHTMLElement2_get_scrollLeft(elem, NULL);
1870     ok(hres == E_INVALIDARG, "expect E_INVALIDARG got 0x%08x\n", hres);
1871
1872     hres = IHTMLElement2_get_scrollLeft(elem, &l);
1873     ok(hres == S_OK, "get_scrollTop failed: %08x\n", hres);
1874     IHTMLElement2_Release(elem);
1875
1876     hres = IUnknown_QueryInterface(unk, &IID_IHTMLTextContainer, (void**)&txtcont);
1877     ok(hres == S_OK, "Could not get IHTMLTextContainer: %08x\n", hres);
1878
1879     hres = IHTMLTextContainer_get_scrollLeft(txtcont, &l2);
1880     IHTMLTextContainer_Release(txtcont);
1881     ok(hres == S_OK, "IHTMLTextContainer::get_scrollLeft failed: %d\n", l2);
1882     ok(l == l2, "unexpected left %d, expected %d\n", l2, l);
1883 }
1884
1885 #define test_img_src(i,s) _test_img_src(__LINE__,i,s)
1886 static void _test_img_src(unsigned line, IUnknown *unk, const char *exsrc)
1887 {
1888     IHTMLImgElement *img = _get_img_iface(line, unk);
1889     BSTR src;
1890     HRESULT hres;
1891
1892     hres = IHTMLImgElement_get_src(img, &src);
1893     IHTMLImgElement_Release(img);
1894     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
1895     ok_(__FILE__,line) (!strcmp_wa(src, exsrc), "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
1896     SysFreeString(src);
1897 }
1898
1899 #define test_img_set_src(u,s) _test_img_set_src(__LINE__,u,s)
1900 static void _test_img_set_src(unsigned line, IUnknown *unk, const char *src)
1901 {
1902     IHTMLImgElement *img = _get_img_iface(line, unk);
1903     BSTR tmp;
1904     HRESULT hres;
1905
1906     tmp = a2bstr(src);
1907     hres = IHTMLImgElement_put_src(img, tmp);
1908     IHTMLImgElement_Release(img);
1909     SysFreeString(tmp);
1910     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
1911
1912     _test_img_src(line, unk, src);
1913 }
1914
1915 #define test_img_alt(u,a) _test_img_alt(__LINE__,u,a)
1916 static void _test_img_alt(unsigned line, IUnknown *unk, const char *exalt)
1917 {
1918     IHTMLImgElement *img = _get_img_iface(line, unk);
1919     BSTR alt;
1920     HRESULT hres;
1921
1922     hres = IHTMLImgElement_get_alt(img, &alt);
1923     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
1924     if(exalt)
1925         ok_(__FILE__,line) (!strcmp_wa(alt, exalt), "inexopected alt %s\n", wine_dbgstr_w(alt));
1926     else
1927         ok_(__FILE__,line) (!alt, "alt != NULL\n");
1928     SysFreeString(alt);
1929 }
1930
1931 #define test_img_set_alt(u,a) _test_img_set_alt(__LINE__,u,a)
1932 static void _test_img_set_alt(unsigned line, IUnknown *unk, const char *alt)
1933 {
1934     IHTMLImgElement *img = _get_img_iface(line, unk);
1935     BSTR tmp;
1936     HRESULT hres;
1937
1938     tmp = a2bstr(alt);
1939     hres = IHTMLImgElement_put_alt(img, tmp);
1940     ok_(__FILE__,line) (hres == S_OK, "get_alt failed: %08x\n", hres);
1941     SysFreeString(tmp);
1942
1943     _test_img_alt(line, unk, alt);
1944 }
1945
1946 #define test_img_name(u, c) _test_img_name(__LINE__,u, c)
1947 static void _test_img_name(unsigned line, IUnknown *unk, const char *pValue)
1948 {
1949     IHTMLImgElement *img = _get_img_iface(line, unk);
1950     BSTR sName;
1951     HRESULT hres;
1952
1953     hres = IHTMLImgElement_get_name(img, &sName);
1954     ok_(__FILE__,line) (hres == S_OK, "get_Name failed: %08x\n", hres);
1955     ok_(__FILE__,line) (!strcmp_wa (sName, pValue), "expected '%s' got '%s'\n", pValue, wine_dbgstr_w(sName));
1956     SysFreeString(sName);
1957 }
1958
1959
1960 #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b)
1961 static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
1962 {
1963     VARIANT_BOOL disabled = 100;
1964     HRESULT hres;
1965
1966     hres = IHTMLInputElement_get_disabled(input, &disabled);
1967     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1968     ok_(__FILE__,line) (disabled == exb, "disabled=%x, expected %x\n", disabled, exb);
1969
1970     _test_elem3_get_disabled(line, (IUnknown*)input, exb);
1971 }
1972
1973 #define test_input_set_disabled(i,b) _test_input_set_disabled(__LINE__,i,b)
1974 static void _test_input_set_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
1975 {
1976     HRESULT hres;
1977
1978     hres = IHTMLInputElement_put_disabled(input, b);
1979     ok_(__FILE__,line) (hres == S_OK, "get_disabled failed: %08x\n", hres);
1980
1981     _test_input_get_disabled(line, input, b);
1982 }
1983
1984 #define test_input_get_defaultchecked(i,b) _test_input_get_defaultchecked(__LINE__,i,b)
1985 static void _test_input_get_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
1986 {
1987     VARIANT_BOOL checked = 100;
1988     HRESULT hres;
1989
1990     hres = IHTMLInputElement_get_defaultChecked(input, &checked);
1991     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
1992     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
1993 }
1994
1995 #define test_input_set_defaultchecked(i,b) _test_input_set_defaultchecked(__LINE__,i,b)
1996 static void _test_input_set_defaultchecked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
1997 {
1998     HRESULT hres;
1999
2000     hres = IHTMLInputElement_put_defaultChecked(input, b);
2001     ok_(__FILE__,line) (hres == S_OK, "get_defaultChecked failed: %08x\n", hres);
2002
2003     _test_input_get_defaultchecked(line, input, b);
2004 }
2005
2006 #define test_input_get_checked(i,b) _test_input_get_checked(__LINE__,i,b)
2007 static void _test_input_get_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
2008 {
2009     VARIANT_BOOL checked = 100;
2010     HRESULT hres;
2011
2012     hres = IHTMLInputElement_get_checked(input, &checked);
2013     ok_(__FILE__,line) (hres == S_OK, "get_checked failed: %08x\n", hres);
2014     ok_(__FILE__,line) (checked == exb, "checked=%x, expected %x\n", checked, exb);
2015 }
2016
2017 #define test_input_set_checked(i,b) _test_input_set_checked(__LINE__,i,b)
2018 static void _test_input_set_checked(unsigned line, IHTMLInputElement *input, VARIANT_BOOL b)
2019 {
2020     HRESULT hres;
2021
2022     hres = IHTMLInputElement_put_checked(input, b);
2023     ok_(__FILE__,line) (hres == S_OK, "get_checked failed: %08x\n", hres);
2024
2025     _test_input_get_checked(line, input, b);
2026 }
2027
2028 #define test_input_value(o,t) _test_input_value(__LINE__,o,t)
2029 static void _test_input_value(unsigned line, IUnknown *unk, const char *exval)
2030 {
2031     IHTMLInputElement *input;
2032     BSTR bstr;
2033     HRESULT hres;
2034
2035     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
2036     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
2037     if(FAILED(hres))
2038         return;
2039
2040     hres = IHTMLInputElement_get_value(input, &bstr);
2041     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
2042     if(exval)
2043         ok_(__FILE__,line) (!strcmp_wa(bstr, exval), "value=%s\n", wine_dbgstr_w(bstr));
2044     else
2045         ok_(__FILE__,line) (!exval, "exval != NULL\n");
2046     SysFreeString(bstr);
2047     IHTMLInputElement_Release(input);
2048 }
2049
2050 #define test_input_put_value(o,v) _test_input_put_value(__LINE__,o,v)
2051 static void _test_input_put_value(unsigned line, IUnknown *unk, const char *val)
2052 {
2053     IHTMLInputElement *input;
2054     BSTR bstr;
2055     HRESULT hres;
2056
2057     hres = IUnknown_QueryInterface(unk, &IID_IHTMLInputElement, (void**)&input);
2058     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
2059     if(FAILED(hres))
2060         return;
2061
2062     bstr = a2bstr(val);
2063     hres = IHTMLInputElement_get_value(input, &bstr);
2064     ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres);
2065     SysFreeString(bstr);
2066     IHTMLInputElement_Release(input);
2067 }
2068
2069 #define test_input_src(i,s) _test_input_src(__LINE__,i,s)
2070 static void _test_input_src(unsigned line, IHTMLInputElement *input, const char *exsrc)
2071 {
2072     BSTR src;
2073     HRESULT hres;
2074
2075     hres = IHTMLInputElement_get_src(input, &src);
2076     ok_(__FILE__,line) (hres == S_OK, "get_src failed: %08x\n", hres);
2077     if(exsrc)
2078         ok_(__FILE__,line) (!strcmp_wa(src, exsrc), "get_src returned %s expected %s\n", wine_dbgstr_w(src), exsrc);
2079     else
2080         ok_(__FILE__,line) (!src, "get_src returned %s expected NULL\n", wine_dbgstr_w(src));
2081     SysFreeString(src);
2082 }
2083
2084 #define test_input_set_src(u,s) _test_input_set_src(__LINE__,u,s)
2085 static void _test_input_set_src(unsigned line, IHTMLInputElement *input, const char *src)
2086 {
2087     BSTR tmp;
2088     HRESULT hres;
2089
2090     tmp = a2bstr(src);
2091     hres = IHTMLInputElement_put_src(input, tmp);
2092     SysFreeString(tmp);
2093     ok_(__FILE__,line) (hres == S_OK, "put_src failed: %08x\n", hres);
2094
2095     _test_input_src(line, input, src);
2096 }
2097
2098 #define test_elem_class(u,c) _test_elem_class(__LINE__,u,c)
2099 static void _test_elem_class(unsigned line, IUnknown *unk, const char *exclass)
2100 {
2101     IHTMLElement *elem = _get_elem_iface(line, unk);
2102     BSTR class = (void*)0xdeadbeef;
2103     HRESULT hres;
2104
2105     hres = IHTMLElement_get_className(elem, &class);
2106     IHTMLElement_Release(elem);
2107     ok_(__FILE__,line) (hres == S_OK, "get_className failed: %08x\n", hres);
2108     if(exclass)
2109         ok_(__FILE__,line) (!strcmp_wa(class, exclass), "unexpected className %s\n", wine_dbgstr_w(class));
2110     else
2111         ok_(__FILE__,line) (!class, "class != NULL\n");
2112     SysFreeString(class);
2113 }
2114
2115 #define test_elem_tabindex(u,i) _test_elem_tabindex(__LINE__,u,i)
2116 static void _test_elem_tabindex(unsigned line, IUnknown *unk, short exindex)
2117 {
2118     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
2119     short index = -3;
2120     HRESULT hres;
2121
2122     hres = IHTMLElement2_get_tabIndex(elem2, &index);
2123     IHTMLElement2_Release(elem2);
2124     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
2125     ok_(__FILE__,line) (index == exindex, "unexpected index %d\n", index);
2126 }
2127
2128 #define test_elem_set_tabindex(u,i) _test_elem_set_tabindex(__LINE__,u,i)
2129 static void _test_elem_set_tabindex(unsigned line, IUnknown *unk, short index)
2130 {
2131     IHTMLElement2 *elem2 = _get_elem2_iface(line, unk);
2132     HRESULT hres;
2133
2134     hres = IHTMLElement2_put_tabIndex(elem2, index);
2135     IHTMLElement2_Release(elem2);
2136     ok_(__FILE__,line) (hres == S_OK, "get_tabIndex failed: %08x\n", hres);
2137
2138     _test_elem_tabindex(line, unk, index);
2139 }
2140
2141 #define test_elem_filters(u) _test_elem_filters(__LINE__,u)
2142 static void _test_elem_filters(unsigned line, IUnknown *unk)
2143 {
2144     IHTMLElement *elem = _get_elem_iface(line, unk);
2145     HRESULT hres;
2146     IHTMLFiltersCollection *filters;
2147
2148     hres = IHTMLElement_get_filters(elem, &filters);
2149     ok_(__FILE__,line) (hres == S_OK || broken(hres == REGDB_E_CLASSNOTREG) /* NT4 */,
2150                         "get_filters failed: %08x\n", hres);
2151     if(hres == S_OK)
2152     {
2153         LONG len;
2154         IDispatchEx *dispex;
2155
2156         hres = IHTMLFiltersCollection_get_length(filters, &len);
2157         ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
2158         ok_(__FILE__,line) (len == 0, "expect 0 got %d\n", len);
2159
2160         hres = IHTMLFiltersCollection_QueryInterface(filters, &IID_IDispatchEx, (void**)&dispex);
2161         ok_(__FILE__,line) (hres == S_OK || broken(hres == E_NOINTERFACE),
2162                             "Could not get IDispatchEx interface: %08x\n", hres);
2163         if(SUCCEEDED(hres)) {
2164             test_disp((IUnknown*)filters, &IID_IHTMLFiltersCollection, "[object]");
2165             IDispatchEx_Release(dispex);
2166         }
2167
2168         IHTMLFiltersCollection_Release(filters);
2169     }
2170
2171     IHTMLElement_Release(elem);
2172 }
2173
2174 #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c)
2175 static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class)
2176 {
2177     IHTMLElement *elem = _get_elem_iface(line, unk);
2178     BSTR tmp;
2179     HRESULT hres;
2180
2181     tmp = class ? a2bstr(class) : NULL;
2182     hres = IHTMLElement_put_className(elem, tmp);
2183     IHTMLElement_Release(elem);
2184     ok_(__FILE__,line) (hres == S_OK, "put_className failed: %08x\n", hres);
2185     SysFreeString(tmp);
2186
2187     _test_elem_class(line, unk, class);
2188 }
2189
2190 #define test_elem_id(e,i) _test_elem_id(__LINE__,e,i)
2191 static void _test_elem_id(unsigned line, IUnknown *unk, const char *exid)
2192 {
2193     IHTMLElement *elem = _get_elem_iface(line, unk);
2194     BSTR id = (void*)0xdeadbeef;
2195     HRESULT hres;
2196
2197     hres = IHTMLElement_get_id(elem, &id);
2198     IHTMLElement_Release(elem);
2199     ok_(__FILE__,line) (hres == S_OK, "get_id failed: %08x\n", hres);
2200
2201     if(exid)
2202         ok_(__FILE__,line) (!strcmp_wa(id, exid), "unexpected id %s\n", wine_dbgstr_w(id));
2203     else
2204         ok_(__FILE__,line) (!id, "id=%s\n", wine_dbgstr_w(id));
2205
2206     SysFreeString(id);
2207 }
2208
2209 #define test_elem_put_id(u,i) _test_elem_put_id(__LINE__,u,i)
2210 static void _test_elem_put_id(unsigned line, IUnknown *unk, const char *new_id)
2211 {
2212     IHTMLElement *elem = _get_elem_iface(line, unk);
2213     BSTR tmp = a2bstr(new_id);
2214     HRESULT hres;
2215
2216     hres = IHTMLElement_put_id(elem, tmp);
2217     IHTMLElement_Release(elem);
2218     SysFreeString(tmp);
2219     ok_(__FILE__,line) (hres == S_OK, "put_id failed: %08x\n", hres);
2220
2221     _test_elem_id(line, unk, new_id);
2222 }
2223
2224 #define test_elem_title(u,t) _test_elem_title(__LINE__,u,t)
2225 static void _test_elem_title(unsigned line, IUnknown *unk, const char *extitle)
2226 {
2227     IHTMLElement *elem = _get_elem_iface(line, unk);
2228     BSTR title;
2229     HRESULT hres;
2230
2231     hres = IHTMLElement_get_title(elem, &title);
2232     IHTMLElement_Release(elem);
2233     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2234     if(extitle)
2235         ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
2236     else
2237         ok_(__FILE__,line) (!title, "title=%s, expected NULL\n", wine_dbgstr_w(title));
2238
2239     SysFreeString(title);
2240 }
2241
2242 #define test_elem_set_title(u,t) _test_elem_set_title(__LINE__,u,t)
2243 static void _test_elem_set_title(unsigned line, IUnknown *unk, const char *title)
2244 {
2245     IHTMLElement *elem = _get_elem_iface(line, unk);
2246     BSTR tmp;
2247     HRESULT hres;
2248
2249     tmp = a2bstr(title);
2250     hres = IHTMLElement_put_title(elem, tmp);
2251     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2252
2253     IHTMLElement_Release(elem);
2254     SysFreeString(tmp);
2255 }
2256
2257 #define test_node_get_value_str(u,e) _test_node_get_value_str(__LINE__,u,e)
2258 static void _test_node_get_value_str(unsigned line, IUnknown *unk, const char *exval)
2259 {
2260     IHTMLDOMNode *node = _get_node_iface(line, unk);
2261     VARIANT var;
2262     HRESULT hres;
2263
2264     hres = IHTMLDOMNode_get_nodeValue(node, &var);
2265     IHTMLDOMNode_Release(node);
2266     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
2267
2268     if(exval) {
2269         ok_(__FILE__,line) (V_VT(&var) == VT_BSTR, "vt=%d\n", V_VT(&var));
2270         ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&var), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&var)));
2271     }else {
2272         ok_(__FILE__,line) (V_VT(&var) == VT_NULL, "vt=%d, expected VT_NULL\n", V_VT(&var));
2273     }
2274
2275     VariantClear(&var);
2276 }
2277
2278 #define test_node_put_value_str(u,v) _test_node_put_value_str(__LINE__,u,v)
2279 static void _test_node_put_value_str(unsigned line, IUnknown *unk, const char *val)
2280 {
2281     IHTMLDOMNode *node = _get_node_iface(line, unk);
2282     VARIANT var;
2283     HRESULT hres;
2284
2285     V_VT(&var) = VT_BSTR;
2286     V_BSTR(&var) = a2bstr(val);
2287
2288     hres = IHTMLDOMNode_put_nodeValue(node, var);
2289     ok_(__FILE__,line) (hres == S_OK, "get_nodeValue failed: %08x, expected VT_BSTR\n", hres);
2290     IHTMLDOMNode_Release(node);
2291     VariantClear(&var);
2292 }
2293
2294 #define test_elem_client_size(u) _test_elem_client_size(__LINE__,u)
2295 static void _test_elem_client_size(unsigned line, IUnknown *unk)
2296 {
2297     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2298     LONG l;
2299     HRESULT hres;
2300
2301     hres = IHTMLElement2_get_clientWidth(elem, &l);
2302     ok_(__FILE__,line) (hres == S_OK, "get_clientWidth failed: %08x\n", hres);
2303     hres = IHTMLElement2_get_clientHeight(elem, &l);
2304     ok_(__FILE__,line) (hres == S_OK, "get_clientHeight failed: %08x\n", hres);
2305
2306     IHTMLElement2_Release(elem);
2307 }
2308
2309 #define test_elem_client_rect(u) _test_elem_client_rect(__LINE__,u)
2310 static void _test_elem_client_rect(unsigned line, IUnknown *unk)
2311 {
2312     IHTMLElement2 *elem = _get_elem2_iface(line, unk);
2313     LONG l;
2314     HRESULT hres;
2315
2316     hres = IHTMLElement2_get_clientLeft(elem, &l);
2317     ok_(__FILE__,line) (hres == S_OK, "get_clientLeft failed: %08x\n", hres);
2318     ok_(__FILE__,line) (!l, "clientLeft = %d\n", l);
2319
2320     hres = IHTMLElement2_get_clientTop(elem, &l);
2321     ok_(__FILE__,line) (hres == S_OK, "get_clientTop failed: %08x\n", hres);
2322     ok_(__FILE__,line) (!l, "clientTop = %d\n", l);
2323
2324     IHTMLElement2_Release(elem);
2325 }
2326
2327 #define get_elem_doc(e) _get_elem_doc(__LINE__,e)
2328 static IHTMLDocument2 *_get_elem_doc(unsigned line, IUnknown *unk)
2329 {
2330     IHTMLElement *elem = _get_elem_iface(line, unk);
2331     IHTMLDocument2 *doc;
2332     IDispatch *disp;
2333     HRESULT hres;
2334
2335     disp = NULL;
2336     hres = IHTMLElement_get_document(elem, &disp);
2337     ok(hres == S_OK, "get_document failed: %08x\n", hres);
2338     ok(disp != NULL, "disp == NULL\n");
2339
2340     hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
2341     IDispatch_Release(disp);
2342     ok(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
2343
2344     return doc;
2345 }
2346
2347 #define get_window_doc(e) _get_window_doc(__LINE__,e)
2348 static IHTMLDocument2 *_get_window_doc(unsigned line, IHTMLWindow2 *window)
2349 {
2350     IHTMLDocument2 *doc;
2351     HRESULT hres;
2352
2353     doc = NULL;
2354     hres = IHTMLWindow2_get_document(window, &doc);
2355     ok(hres == S_OK, "get_document failed: %08x\n", hres);
2356     ok(doc != NULL, "disp == NULL\n");
2357
2358     return doc;
2359 }
2360
2361 #define test_create_elem(d,t) _test_create_elem(__LINE__,d,t)
2362 static IHTMLElement *_test_create_elem(unsigned line, IHTMLDocument2 *doc, const char *tag)
2363 {
2364     IHTMLElement *elem = NULL;
2365     BSTR tmp;
2366     HRESULT hres;
2367
2368     tmp = a2bstr(tag);
2369     hres = IHTMLDocument2_createElement(doc, tmp, &elem);
2370     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
2371     ok_(__FILE__,line) (elem != NULL, "elem == NULL\n");
2372
2373     return elem;
2374 }
2375
2376 #define test_create_text(d,t) _test_create_text(__LINE__,d,t)
2377 static IHTMLDOMNode *_test_create_text(unsigned line, IHTMLDocument2 *doc, const char *text)
2378 {
2379     IHTMLDocument3 *doc3;
2380     IHTMLDOMNode *node = NULL;
2381     BSTR tmp;
2382     HRESULT hres;
2383
2384     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
2385     ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3: %08x\n", hres);
2386
2387     tmp = a2bstr(text);
2388     hres = IHTMLDocument3_createTextNode(doc3, tmp, &node);
2389     IHTMLDocument3_Release(doc3);
2390     ok_(__FILE__,line) (hres == S_OK, "createElement failed: %08x\n", hres);
2391     ok_(__FILE__,line) (node != NULL, "node == NULL\n");
2392
2393     return node;
2394 }
2395
2396 #define test_node_append_child(n,c) _test_node_append_child(__LINE__,n,c)
2397 static IHTMLDOMNode *_test_node_append_child(unsigned line, IUnknown *node_unk, IUnknown *child_unk)
2398 {
2399     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
2400     IHTMLDOMNode *child = _get_node_iface(line, child_unk);
2401     IHTMLDOMNode *new_child = NULL;
2402     HRESULT hres;
2403
2404     hres = IHTMLDOMNode_appendChild(node, child, &new_child);
2405     ok_(__FILE__,line) (hres == S_OK, "appendChild failed: %08x\n", hres);
2406     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
2407     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
2408
2409     IHTMLDOMNode_Release(node);
2410     IHTMLDOMNode_Release(child);
2411
2412     return new_child;
2413 }
2414
2415 #define test_node_insertbefore(n,c,v) _test_node_insertbefore(__LINE__,n,c,v)
2416 static IHTMLDOMNode *_test_node_insertbefore(unsigned line, IUnknown *node_unk, IHTMLDOMNode *child, VARIANT *var)
2417 {
2418     IHTMLDOMNode *node = _get_node_iface(line, node_unk);
2419     IHTMLDOMNode *new_child = NULL;
2420     HRESULT hres;
2421
2422     hres = IHTMLDOMNode_insertBefore(node, child, *var, &new_child);
2423     ok_(__FILE__,line) (hres == S_OK, "insertBefore failed: %08x\n", hres);
2424     ok_(__FILE__,line) (new_child != NULL, "new_child == NULL\n");
2425     /* TODO  ok_(__FILE__,line) (new_child != child, "new_child == child\n"); */
2426
2427     IHTMLDOMNode_Release(node);
2428
2429     return new_child;
2430 }
2431
2432 #define test_node_remove_child(n,c) _test_node_remove_child(__LINE__,n,c)
2433 static void _test_node_remove_child(unsigned line, IUnknown *unk, IHTMLDOMNode *child)
2434 {
2435     IHTMLDOMNode *node = _get_node_iface(line, unk);
2436     IHTMLDOMNode *new_node = NULL;
2437     HRESULT hres;
2438
2439     hres = IHTMLDOMNode_removeChild(node, child, &new_node);
2440     ok_(__FILE__,line) (hres == S_OK, "removeChild failed: %08x\n", hres);
2441     ok_(__FILE__,line) (new_node != NULL, "new_node == NULL\n");
2442     /* TODO ok_(__FILE__,line) (new_node != child, "new_node == child\n"); */
2443
2444     IHTMLDOMNode_Release(node);
2445     IHTMLDOMNode_Release(new_node);
2446 }
2447
2448 #define test_doc_title(d,t) _test_doc_title(__LINE__,d,t)
2449 static void _test_doc_title(unsigned line, IHTMLDocument2 *doc, const char *extitle)
2450 {
2451     BSTR title = NULL;
2452     HRESULT hres;
2453
2454     hres = IHTMLDocument2_get_title(doc, &title);
2455     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2456     ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", wine_dbgstr_w(title));
2457     SysFreeString(title);
2458 }
2459
2460 #define test_doc_set_title(d,t) _test_doc_set_title(__LINE__,d,t)
2461 static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const char *title)
2462 {
2463     BSTR tmp;
2464     HRESULT hres;
2465
2466     tmp = a2bstr(title);
2467     hres = IHTMLDocument2_put_title(doc, tmp);
2468     ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres);
2469     SysFreeString(tmp);
2470 }
2471
2472 #define test_border_styles(p, n) _test_border_styles(__LINE__, p, n)
2473 static void _test_border_styles(unsigned line, IHTMLStyle *pStyle, BSTR Name)
2474 {
2475     HRESULT hres;
2476     DISPID dispid;
2477
2478     hres = IHTMLStyle_GetIDsOfNames(pStyle, &IID_NULL, &Name, 1,
2479                         LOCALE_USER_DEFAULT, &dispid);
2480     ok_(__FILE__,line) (hres == S_OK, "GetIDsOfNames: %08x\n", hres);
2481     if(hres == S_OK)
2482     {
2483         DISPPARAMS params = {NULL,NULL,0,0};
2484         DISPID dispidNamed = DISPID_PROPERTYPUT;
2485         VARIANT ret;
2486         VARIANT vDefault;
2487         VARIANTARG arg;
2488
2489         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2490             DISPATCH_PROPERTYGET, &params, &vDefault, NULL, NULL);
2491         ok_(__FILE__,line) (hres == S_OK, "get_default. ret: %08x\n", hres);
2492
2493         params.cArgs = 1;
2494         params.cNamedArgs = 1;
2495         params.rgdispidNamedArgs = &dispidNamed;
2496         V_VT(&arg) = VT_BSTR;
2497         V_BSTR(&arg) = a2bstr("none");
2498         params.rgvarg = &arg;
2499         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2500             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2501         ok_(__FILE__,line) (hres == S_OK, "none. ret: %08x\n", hres);
2502         VariantClear(&arg);
2503
2504         V_VT(&arg) = VT_BSTR;
2505         V_BSTR(&arg) = a2bstr("dotted");
2506         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2507             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2508         ok_(__FILE__,line) (hres == S_OK, "dotted. ret: %08x\n", hres);
2509         VariantClear(&arg);
2510
2511         V_VT(&arg) = VT_BSTR;
2512         V_BSTR(&arg) = a2bstr("dashed");
2513         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2514         DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2515         ok_(__FILE__,line) (hres == S_OK, "dashed. ret: %08x\n", hres);
2516         VariantClear(&arg);
2517
2518         V_VT(&arg) = VT_BSTR;
2519         V_BSTR(&arg) = a2bstr("solid");
2520         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2521             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2522         ok_(__FILE__,line) (hres == S_OK, "solid. ret: %08x\n", hres);
2523         VariantClear(&arg);
2524
2525         V_VT(&arg) = VT_BSTR;
2526         V_BSTR(&arg) = a2bstr("double");
2527         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2528             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2529         ok_(__FILE__,line) (hres == S_OK, "double. ret: %08x\n", hres);
2530         VariantClear(&arg);
2531
2532         V_VT(&arg) = VT_BSTR;
2533         V_BSTR(&arg) = a2bstr("groove");
2534         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2535             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2536         ok_(__FILE__,line) (hres == S_OK, "groove. ret: %08x\n", hres);
2537         VariantClear(&arg);
2538
2539         V_VT(&arg) = VT_BSTR;
2540         V_BSTR(&arg) = a2bstr("ridge");
2541         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2542             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2543         ok_(__FILE__,line) (hres == S_OK, "ridge. ret: %08x\n", hres);
2544         VariantClear(&arg);
2545
2546         V_VT(&arg) = VT_BSTR;
2547         V_BSTR(&arg) = a2bstr("inset");
2548         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2549             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2550         ok_(__FILE__,line) (hres == S_OK, "inset. ret: %08x\n", hres);
2551         VariantClear(&arg);
2552
2553         V_VT(&arg) = VT_BSTR;
2554         V_BSTR(&arg) = a2bstr("outset");
2555         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2556             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2557         ok_(__FILE__,line) (hres == S_OK, "outset. ret: %08x\n", hres);
2558         VariantClear(&arg);
2559
2560         V_VT(&arg) = VT_BSTR;
2561         V_BSTR(&arg) = a2bstr("invalid");
2562         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2563             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2564         ok_(__FILE__,line) (FAILED(hres), "invalid value passed.\n");
2565         VariantClear(&arg);
2566
2567         params.rgvarg = &vDefault;
2568         hres = IHTMLStyle_Invoke(pStyle, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2569             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2570         ok_(__FILE__,line) (hres == S_OK, "default. ret: %08x\n", hres);
2571     }
2572 }
2573
2574 #define test_style_csstext(s,t) _test_style_csstext(__LINE__,s,t)
2575 static void _test_style_csstext(unsigned line, IHTMLStyle *style, const char *extext)
2576 {
2577     BSTR text = (void*)0xdeadbeef;
2578     HRESULT hres;
2579
2580     hres = IHTMLStyle_get_cssText(style, &text);
2581     ok_(__FILE__,line)(hres == S_OK, "get_cssText failed: %08x\n", hres);
2582     if(extext)
2583         ok_(__FILE__,line)(!strcmp_wa(text, extext), "cssText = %s\n", wine_dbgstr_w(text));
2584     else
2585         ok_(__FILE__,line)(!text, "cssText = %s\n", wine_dbgstr_w(text));
2586
2587     SysFreeString(text);
2588 }
2589
2590 #define test_style_set_csstext(s,t) _test_style_set_csstext(__LINE__,s,t)
2591 static void _test_style_set_csstext(unsigned line, IHTMLStyle *style, const char *text)
2592 {
2593     BSTR tmp;
2594     HRESULT hres;
2595
2596     tmp = a2bstr(text);
2597     hres = IHTMLStyle_put_cssText(style, tmp);
2598     ok_(__FILE__,line)(hres == S_OK, "put_cssText failed: %08x\n", hres);
2599     SysFreeString(tmp);
2600 }
2601
2602 static void test_elem_col_item(IHTMLElementCollection *col, const char *n,
2603         const elem_type_t *elem_types, LONG len)
2604 {
2605     IDispatch *disp;
2606     VARIANT name, index;
2607     DWORD i;
2608     HRESULT hres;
2609
2610     V_VT(&index) = VT_EMPTY;
2611     V_VT(&name) = VT_BSTR;
2612     V_BSTR(&name) = a2bstr(n);
2613
2614     hres = IHTMLElementCollection_item(col, name, index, &disp);
2615     ok(hres == S_OK, "item failed: %08x\n", hres);
2616
2617     test_elem_collection((IUnknown*)disp, elem_types, len);
2618     IDispatch_Release(disp);
2619     ok(hres == S_OK, "Could not get IHTMLElementCollection interface: %08x\n", hres);
2620     if(hres != S_OK)
2621         goto cleanup;
2622
2623     V_VT(&index) = VT_I4;
2624
2625     for(i=0; i<len; i++) {
2626         V_I4(&index) = i;
2627         disp = (void*)0xdeadbeef;
2628         hres = IHTMLElementCollection_item(col, name, index, &disp);
2629         ok(hres == S_OK, "item failed: %08x\n", hres);
2630         ok(disp != NULL, "disp == NULL\n");
2631         if(FAILED(hres) || !disp)
2632             continue;
2633
2634         test_elem_type((IUnknown*)disp, elem_types[i]);
2635
2636         IDispatch_Release(disp);
2637     }
2638
2639     V_I4(&index) = len;
2640     disp = (void*)0xdeadbeef;
2641     hres = IHTMLElementCollection_item(col, name, index, &disp);
2642     ok(hres == S_OK, "item failed: %08x\n", hres);
2643     ok(disp == NULL, "disp != NULL\n");
2644
2645     V_I4(&index) = -1;
2646     disp = (void*)0xdeadbeef;
2647     hres = IHTMLElementCollection_item(col, name, index, &disp);
2648     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
2649     ok(disp == NULL, "disp != NULL\n");
2650
2651 cleanup:
2652     SysFreeString(V_BSTR(&name));
2653 }
2654
2655 static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const char *id, BOOL expect_success)
2656 {
2657     IHTMLElementCollection *col;
2658     IHTMLElement *elem;
2659     IDispatch *disp = (void*)0xdeadbeef;
2660     VARIANT name, index;
2661     HRESULT hres;
2662
2663     hres = IHTMLDocument2_get_all(doc, &col);
2664     ok(hres == S_OK, "get_all failed: %08x\n", hres);
2665     ok(col != NULL, "col == NULL\n");
2666     if(FAILED(hres) || !col)
2667         return NULL;
2668
2669     V_VT(&index) = VT_EMPTY;
2670     V_VT(&name) = VT_BSTR;
2671     V_BSTR(&name) = a2bstr(id);
2672
2673     hres = IHTMLElementCollection_item(col, name, index, &disp);
2674     IHTMLElementCollection_Release(col);
2675     SysFreeString(V_BSTR(&name));
2676     ok(hres == S_OK, "item failed: %08x\n", hres);
2677     if(!expect_success) {
2678         ok(disp == NULL, "disp != NULL\n");
2679         return NULL;
2680     }
2681
2682     ok(disp != NULL, "disp == NULL\n");
2683     if(!disp)
2684         return NULL;
2685
2686     elem = get_elem_iface((IUnknown*)disp);
2687     IDispatch_Release(disp);
2688
2689     return elem;
2690 }
2691
2692 static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const char *id)
2693 {
2694     IHTMLDocument3 *doc3;
2695     IHTMLElement *elem;
2696     BSTR tmp;
2697     HRESULT hres;
2698
2699     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
2700     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
2701
2702     tmp = a2bstr(id);
2703     hres = IHTMLDocument3_getElementById(doc3, tmp, &elem);
2704     SysFreeString(tmp);
2705     ok(hres == S_OK, "getElementById(%s) failed: %08x\n", id, hres);
2706
2707     IHTMLDocument3_Release(doc3);
2708
2709     return elem;
2710 }
2711
2712 static void test_select_elem(IHTMLSelectElement *select)
2713 {
2714     test_select_type(select, "select-one");
2715     test_select_length(select, 2);
2716     test_select_selidx(select, 0);
2717     test_select_put_selidx(select, 1);
2718
2719     test_select_set_value(select, "val1");
2720     test_select_value(select, "val1");
2721
2722     test_select_get_disabled(select, VARIANT_FALSE);
2723     test_select_set_disabled(select, VARIANT_TRUE);
2724     test_select_set_disabled(select, VARIANT_FALSE);
2725 }
2726
2727 static void test_create_option_elem(IHTMLDocument2 *doc)
2728 {
2729     IHTMLOptionElement *option;
2730
2731     option = create_option_elem(doc, "test text", "test value");
2732
2733     test_option_put_text(option, "new text");
2734     test_option_put_value(option, "new value");
2735
2736     IHTMLOptionElement_Release(option);
2737 }
2738
2739 static void test_create_img_elem(IHTMLDocument2 *doc)
2740 {
2741     IHTMLImgElement *img;
2742
2743     img = create_img_elem(doc, 10, 15);
2744
2745     if(img){
2746         test_img_put_width(img, 5);
2747         test_img_put_height(img, 20);
2748
2749         IHTMLImgElement_Release(img);
2750         img = NULL;
2751     }
2752
2753     img = create_img_elem(doc, -1, -1);
2754
2755     if(img){
2756         test_img_put_width(img, 5);
2757         test_img_put_height(img, 20);
2758
2759         IHTMLImgElement_Release(img);
2760     }
2761 }
2762
2763 static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
2764 {
2765     IHTMLBodyElement *body;
2766     IHTMLTxtRange *range;
2767     IHTMLElement *elem;
2768     HRESULT hres;
2769
2770     hres = IHTMLDocument2_get_body(doc, &elem);
2771     ok(hres == S_OK, "get_body failed: %08x\n", hres);
2772
2773     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
2774     IHTMLElement_Release(elem);
2775
2776     hres = IHTMLBodyElement_createTextRange(body, &range);
2777     IHTMLBodyElement_Release(body);
2778     ok(hres == S_OK, "createTextRange failed: %08x\n", hres);
2779
2780     return range;
2781 }
2782
2783 static void test_txtrange(IHTMLDocument2 *doc)
2784 {
2785     IHTMLTxtRange *body_range, *range, *range2;
2786     IHTMLSelectionObject *selection;
2787     IDispatch *disp_range;
2788     HRESULT hres;
2789
2790     body_range = test_create_body_range(doc);
2791
2792     test_range_text(body_range, "test abc 123\r\nit's text");
2793
2794     hres = IHTMLTxtRange_duplicate(body_range, &range);
2795     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2796
2797     hres = IHTMLTxtRange_duplicate(body_range, &range2);
2798     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2799     test_range_isequal(range, range2, VARIANT_TRUE);
2800
2801     test_range_text(range, "test abc 123\r\nit's text");
2802     test_range_text(body_range, "test abc 123\r\nit's text");
2803
2804     test_range_collapse(range, TRUE);
2805     test_range_isequal(range, range2, VARIANT_FALSE);
2806     test_range_inrange(range, range2, VARIANT_FALSE);
2807     test_range_inrange(range2, range, VARIANT_TRUE);
2808     IHTMLTxtRange_Release(range2);
2809
2810     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
2811     test_range_expand(range, wordW, VARIANT_FALSE, "test ");
2812     test_range_move(range, characterW, 2, 2);
2813     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
2814
2815     test_range_collapse(range, FALSE);
2816     test_range_expand(range, wordW, VARIANT_TRUE, "abc ");
2817
2818     test_range_collapse(range, FALSE);
2819     test_range_expand(range, wordW, VARIANT_TRUE, "123");
2820     test_range_expand(range, wordW, VARIANT_FALSE, "123");
2821     test_range_move(range, characterW, 2, 2);
2822     test_range_expand(range, wordW, VARIANT_TRUE, "123");
2823     test_range_moveend(range, characterW, -5, -5);
2824     test_range_text(range, NULL);
2825     test_range_moveend(range, characterW, 3, 3);
2826     test_range_text(range, "c 1");
2827     test_range_expand(range, texteditW, VARIANT_TRUE, "test abc 123\r\nit's text");
2828     test_range_collapse(range, TRUE);
2829     test_range_move(range, characterW, 4, 4);
2830     test_range_moveend(range, characterW, 1, 1);
2831     test_range_text(range, " ");
2832     test_range_move(range, wordW, 1, 1);
2833     test_range_moveend(range, characterW, 2, 2);
2834     test_range_text(range, "ab");
2835
2836     IHTMLTxtRange_Release(range);
2837
2838     hres = IHTMLTxtRange_duplicate(body_range, &range);
2839     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2840
2841     test_range_text(range, "test abc 123\r\nit's text");
2842     test_range_move(range, characterW, 3, 3);
2843     test_range_moveend(range, characterW, 1, 1);
2844     test_range_text(range, "t");
2845     test_range_moveend(range, characterW, 3, 3);
2846     test_range_text(range, "t ab");
2847     test_range_moveend(range, characterW, -2, -2);
2848     test_range_text(range, "t ");
2849     test_range_move(range, characterW, 6, 6);
2850     test_range_moveend(range, characterW, 3, 3);
2851     test_range_text(range, "123");
2852     test_range_moveend(range, characterW, 2, 2);
2853     test_range_text(range, "123\r\ni");
2854
2855     IHTMLTxtRange_Release(range);
2856
2857     hres = IHTMLTxtRange_duplicate(body_range, &range);
2858     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2859
2860     test_range_move(range, wordW, 1, 1);
2861     test_range_moveend(range, characterW, 2, 2);
2862     test_range_text(range, "ab");
2863
2864     test_range_move(range, characterW, -2, -2);
2865     test_range_moveend(range, characterW, 2, 2);
2866     test_range_text(range, "t ");
2867
2868     test_range_move(range, wordW, 3, 3);
2869     test_range_move(range, wordW, -2, -2);
2870     test_range_moveend(range, characterW, 2, 2);
2871     test_range_text(range, "ab");
2872
2873     test_range_move(range, characterW, -6, -5);
2874     test_range_moveend(range, characterW, -1, 0);
2875     test_range_moveend(range, characterW, -6, 0);
2876     test_range_move(range, characterW, 2, 2);
2877     test_range_moveend(range, characterW, 2, 2);
2878     test_range_text(range, "st");
2879     test_range_moveend(range, characterW, -6, -4);
2880     test_range_moveend(range, characterW, 2, 2);
2881
2882     IHTMLTxtRange_Release(range);
2883
2884     hres = IHTMLTxtRange_duplicate(body_range, &range);
2885     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2886
2887     test_range_move(range, wordW, 2, 2);
2888     test_range_moveend(range, characterW, 2, 2);
2889     test_range_text(range, "12");
2890
2891     test_range_move(range, characterW, 15, 14);
2892     test_range_move(range, characterW, -2, -2);
2893     test_range_moveend(range, characterW, 3, 2);
2894     test_range_text(range, "t");
2895     test_range_moveend(range, characterW, -1, -1);
2896     test_range_text(range, "t");
2897     test_range_expand(range, wordW, VARIANT_TRUE, "text");
2898     test_range_move(range, characterW, -2, -2);
2899     test_range_moveend(range, characterW, 2, 2);
2900     test_range_text(range, "s ");
2901     test_range_move(range, characterW, 100, 7);
2902     test_range_move(range, wordW, 1, 0);
2903     test_range_move(range, characterW, -2, -2);
2904     test_range_moveend(range, characterW, 3, 2);
2905     test_range_text(range, "t");
2906
2907     IHTMLTxtRange_Release(range);
2908
2909     hres = IHTMLTxtRange_duplicate(body_range, &range);
2910     ok(hres == S_OK, "duplicate failed: %08x\n", hres);
2911
2912     test_range_collapse(range, TRUE);
2913     test_range_expand(range, wordW, VARIANT_TRUE, "test ");
2914     test_range_put_text(range, "word");
2915     test_range_text(body_range, "wordabc 123\r\nit's text");
2916     test_range_text(range, NULL);
2917     test_range_moveend(range, characterW, 3, 3);
2918     test_range_text(range, "abc");
2919     test_range_movestart(range, characterW, -2, -2);
2920     test_range_text(range, "rdabc");
2921     test_range_movestart(range, characterW, 3, 3);
2922     test_range_text(range, "bc");
2923     test_range_movestart(range, characterW, 4, 4);
2924     test_range_text(range, NULL);
2925     test_range_movestart(range, characterW, -3, -3);
2926     test_range_text(range, "c 1");
2927     test_range_movestart(range, characterW, -7, -6);
2928     test_range_text(range, "wordabc 1");
2929     test_range_movestart(range, characterW, 100, 22);
2930     test_range_text(range, NULL);
2931
2932     IHTMLTxtRange_Release(range);
2933     IHTMLTxtRange_Release(body_range);
2934
2935     hres = IHTMLDocument2_get_selection(doc, &selection);
2936     ok(hres == S_OK, "IHTMLDocument2_get_selection failed: %08x\n", hres);
2937
2938     hres = IHTMLSelectionObject_createRange(selection, &disp_range);
2939     ok(hres == S_OK, "IHTMLSelectionObject_createRange failed: %08x\n", hres);
2940     IHTMLSelectionObject_Release(selection);
2941
2942     hres = IDispatch_QueryInterface(disp_range, &IID_IHTMLTxtRange, (void **)&range);
2943     ok(hres == S_OK, "Could not get IID_IHTMLTxtRange interface: 0x%08x\n", hres);
2944     IDispatch_Release(disp_range);
2945
2946     test_range_text(range, NULL);
2947     test_range_moveend(range, characterW, 3, 3);
2948     test_range_text(range, "wor");
2949     test_range_parent(range, ET_BODY);
2950     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
2951     test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
2952     test_range_move(range, characterW, 3, 3);
2953     test_range_expand(range, wordW, VARIANT_TRUE, "wordabc ");
2954     test_range_moveend(range, characterW, -4, -4);
2955     test_range_put_text(range, "abc def ");
2956     test_range_expand(range, texteditW, VARIANT_TRUE, "abc def abc 123\r\nit's text");
2957     test_range_move(range, wordW, 1, 1);
2958     test_range_movestart(range, characterW, -1, -1);
2959     test_range_text(range, " ");
2960     test_range_move(range, wordW, 1, 1);
2961     test_range_moveend(range, characterW, 3, 3);
2962     test_range_text(range, "def");
2963     test_range_put_text(range, "xyz");
2964     test_range_moveend(range, characterW, 1, 1);
2965     test_range_move(range, wordW, 1, 1);
2966     test_range_moveend(range, characterW, 2, 2);
2967     test_range_text(range, "ab");
2968
2969     IHTMLTxtRange_Release(range);
2970 }
2971
2972 static void test_txtrange2(IHTMLDocument2 *doc)
2973 {
2974     IHTMLTxtRange *range;
2975
2976     range = test_create_body_range(doc);
2977
2978     test_range_text(range, "abc\r\n\r\n123\r\n\r\n\r\ndef");
2979     test_range_move(range, characterW, 5, 5);
2980     test_range_moveend(range, characterW, 1, 1);
2981     test_range_text(range, "2");
2982     test_range_move(range, characterW, -3, -3);
2983     test_range_moveend(range, characterW, 3, 3);
2984     test_range_text(range, "c\r\n\r\n1");
2985     test_range_collapse(range, VARIANT_FALSE);
2986     test_range_moveend(range, characterW, 4, 4);
2987     test_range_text(range, "23");
2988     test_range_moveend(range, characterW, 1, 1);
2989     test_range_text(range, "23\r\n\r\n\r\nd");
2990     test_range_moveend(range, characterW, -1, -1);
2991     test_range_text(range, "23");
2992     test_range_moveend(range, characterW, -1, -1);
2993     test_range_text(range, "23");
2994     test_range_moveend(range, characterW, -2, -2);
2995     test_range_text(range, "2");
2996
2997     IHTMLTxtRange_Release(range);
2998 }
2999
3000 static void test_compatmode(IHTMLDocument2 *doc)
3001 {
3002     IHTMLDocument5 *doc5;
3003     BSTR mode;
3004     HRESULT hres;
3005
3006     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
3007     ok(hres == S_OK, "Could not get IHTMLDocument5 interface: %08x\n", hres);
3008     if(FAILED(hres))
3009         return;
3010
3011     hres = IHTMLDocument5_get_compatMode(doc5, &mode);
3012     IHTMLDocument5_Release(doc5);
3013     ok(hres == S_OK, "get_compatMode failed: %08x\n", hres);
3014     ok(!strcmp_wa(mode, "BackCompat"), "compatMode=%s\n", wine_dbgstr_w(mode));
3015     SysFreeString(mode);
3016 }
3017
3018 static void test_location(IHTMLDocument2 *doc)
3019 {
3020     IHTMLLocation *location, *location2;
3021     IHTMLWindow2 *window;
3022     BSTR str;
3023     ULONG ref;
3024     HRESULT hres;
3025
3026     hres = IHTMLDocument2_get_location(doc, &location);
3027     ok(hres == S_OK, "get_location failed: %08x\n", hres);
3028
3029     hres = IHTMLDocument2_get_location(doc, &location2);
3030     ok(hres == S_OK, "get_location failed: %08x\n", hres);
3031
3032     ok(location == location2, "location != location2\n");
3033     IHTMLLocation_Release(location2);
3034
3035     hres = IHTMLDocument2_get_parentWindow(doc, &window);
3036     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
3037
3038     hres = IHTMLWindow2_get_location(window, &location2);
3039     ok(hres == S_OK, "get_location failed: %08x\n", hres);
3040     ok(location == location2, "location != location2\n");
3041     IHTMLLocation_Release(location2);
3042
3043     test_ifaces((IUnknown*)location, location_iids);
3044     test_disp2((IUnknown*)location, &DIID_DispHTMLLocation, &IID_IHTMLLocation, "about:blank");
3045
3046     hres = IHTMLLocation_get_pathname(location, &str);
3047     ok(hres == S_OK, "get_pathname failed: %08x\n", hres);
3048     ok(!strcmp_wa(str, "blank"), "unexpected pathname %s\n", wine_dbgstr_w(str));
3049
3050     hres = IHTMLLocation_get_href(location, NULL);
3051     ok(hres == E_POINTER, "get_href passed: %08x\n", hres);
3052
3053     hres = IHTMLLocation_get_href(location, &str);
3054     ok(hres == S_OK, "get_href failed: %08x\n", hres);
3055     ok(!strcmp_wa(str, "about:blank"), "unexpected href %s\n", wine_dbgstr_w(str));
3056
3057     ref = IHTMLLocation_Release(location);
3058     ok(!ref, "location chould be destroyed here\n");
3059 }
3060
3061 static void test_navigator(IHTMLDocument2 *doc)
3062 {
3063     IHTMLWindow2 *window;
3064     IOmNavigator *navigator, *navigator2;
3065     char buf[512];
3066     DWORD size;
3067     ULONG ref;
3068     BSTR bstr;
3069     HRESULT hres;
3070
3071     static const WCHAR v40[] = {'4','.','0'};
3072
3073     hres = IHTMLDocument2_get_parentWindow(doc, &window);
3074     ok(hres == S_OK, "parentWidnow failed: %08x\n", hres);
3075
3076     hres = IHTMLWindow2_get_navigator(window, &navigator);
3077     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
3078     ok(navigator != NULL, "navigator == NULL\n");
3079     test_disp2((IUnknown*)navigator, &DIID_DispHTMLNavigator, &IID_IOmNavigator, "[object]");
3080
3081     hres = IHTMLWindow2_get_navigator(window, &navigator2);
3082     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
3083     ok(navigator != navigator2, "navigator2 != navihgator\n");
3084
3085     IHTMLWindow2_Release(window);
3086     IOmNavigator_Release(navigator2);
3087
3088     hres = IOmNavigator_get_appCodeName(navigator, &bstr);
3089     ok(hres == S_OK, "get_appCodeName failed: %08x\n", hres);
3090     ok(!strcmp_wa(bstr, "Mozilla"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
3091     SysFreeString(bstr);
3092
3093     bstr = NULL;
3094     hres = IOmNavigator_get_appName(navigator, &bstr);
3095     ok(hres == S_OK, "get_appName failed: %08x\n", hres);
3096     ok(!strcmp_wa(bstr, "Microsoft Internet Explorer"), "Unexpected appCodeName %s\n", wine_dbgstr_w(bstr));
3097     SysFreeString(bstr);
3098
3099     bstr = NULL;
3100     hres = IOmNavigator_get_platform(navigator, &bstr);
3101     ok(hres == S_OK, "get_platform failed: %08x\n", hres);
3102 #ifdef _WIN64
3103     ok(!strcmp_wa(bstr, "Win64"), "unexpected platform %s\n", wine_dbgstr_w(bstr));
3104 #else
3105     ok(!strcmp_wa(bstr, "Win32"), "unexpected platform %s\n", wine_dbgstr_w(bstr));
3106 #endif
3107     SysFreeString(bstr);
3108
3109     bstr = NULL;
3110     hres = IOmNavigator_get_appVersion(navigator, &bstr);
3111     ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
3112     ok(!memcmp(bstr, v40, sizeof(v40)), "appVersion is %s\n", wine_dbgstr_w(bstr));
3113     SysFreeString(bstr);
3114
3115     hres = IOmNavigator_toString(navigator, NULL);
3116     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
3117
3118     bstr = NULL;
3119     hres = IOmNavigator_toString(navigator, &bstr);
3120     ok(hres == S_OK, "toString failed: %08x\n", hres);
3121     ok(!strcmp_wa(bstr, "[object]"), "toString returned %s\n", wine_dbgstr_w(bstr));
3122     SysFreeString(bstr);
3123
3124     size = sizeof(buf);
3125     hres = ObtainUserAgentString(0, buf, &size);
3126     ok(hres == S_OK, "ObtainUserAgentString failed: %08x\n", hres);
3127
3128     bstr = NULL;
3129     hres = IOmNavigator_get_userAgent(navigator, &bstr);
3130     ok(hres == S_OK, "get_userAgent failed: %08x\n", hres);
3131     ok(!strcmp_wa(bstr, buf), "userAgent returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf);
3132     SysFreeString(bstr);
3133
3134     ref = IOmNavigator_Release(navigator);
3135     ok(!ref, "navigator should be destroyed here\n");
3136 }
3137
3138 static void test_screen(IHTMLWindow2 *window)
3139 {
3140     IHTMLScreen *screen, *screen2;
3141     IDispatchEx *dispex;
3142     LONG l, exl;
3143     HDC hdc;
3144     HRESULT hres;
3145
3146     static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
3147
3148     screen = NULL;
3149     hres = IHTMLWindow2_get_screen(window, &screen);
3150     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
3151     ok(screen != NULL, "screen == NULL\n");
3152
3153     screen2 = NULL;
3154     hres = IHTMLWindow2_get_screen(window, &screen2);
3155     ok(hres == S_OK, "get_screen failed: %08x\n", hres);
3156     ok(screen2 != NULL, "screen == NULL\n");
3157     ok(iface_cmp((IUnknown*)screen2, (IUnknown*)screen), "screen2 != screen\n");
3158     IHTMLScreen_Release(screen2);
3159
3160     hres = IHTMLScreen_QueryInterface(screen, &IID_IDispatchEx, (void**)&dispex);
3161     ok(hres == S_OK || broken(hres == E_NOINTERFACE), "Could not get IDispatchEx interface: %08x\n", hres);
3162     if(SUCCEEDED(hres)) {
3163         test_disp((IUnknown*)screen, &DIID_DispHTMLScreen, "[object]");
3164         IDispatchEx_Release(dispex);
3165     }
3166
3167     hdc = CreateICW(displayW, NULL, NULL, NULL);
3168
3169     exl = GetDeviceCaps(hdc, HORZRES);
3170     l = 0xdeadbeef;
3171     hres = IHTMLScreen_get_width(screen, &l);
3172     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3173     ok(l == exl, "width = %d, expected %d\n", l, exl);
3174
3175     exl = GetDeviceCaps(hdc, VERTRES);
3176     l = 0xdeadbeef;
3177     hres = IHTMLScreen_get_height(screen, &l);
3178     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3179     ok(l == exl, "height = %d, expected %d\n", l, exl);
3180
3181     exl = GetDeviceCaps(hdc, BITSPIXEL);
3182     l = 0xdeadbeef;
3183     hres = IHTMLScreen_get_colorDepth(screen, &l);
3184     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3185     ok(l == exl, "height = %d, expected %d\n", l, exl);
3186
3187     DeleteObject(hdc);
3188
3189     IHTMLScreen_Release(screen);
3190 }
3191
3192 static void test_current_style(IHTMLCurrentStyle *current_style)
3193 {
3194     BSTR str;
3195     HRESULT hres;
3196     VARIANT v;
3197
3198     test_disp((IUnknown*)current_style, &DIID_DispHTMLCurrentStyle, "[object]");
3199     test_ifaces((IUnknown*)current_style, cstyle_iids);
3200
3201     hres = IHTMLCurrentStyle_get_display(current_style, &str);
3202     ok(hres == S_OK, "get_display failed: %08x\n", hres);
3203     ok(!strcmp_wa(str, "block"), "get_display returned %s\n", wine_dbgstr_w(str));
3204     SysFreeString(str);
3205
3206     hres = IHTMLCurrentStyle_get_position(current_style, &str);
3207     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3208     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
3209     SysFreeString(str);
3210
3211     hres = IHTMLCurrentStyle_get_fontFamily(current_style, &str);
3212     ok(hres == S_OK, "get_fontFamily failed: %08x\n", hres);
3213     SysFreeString(str);
3214
3215     hres = IHTMLCurrentStyle_get_fontStyle(current_style, &str);
3216     ok(hres == S_OK, "get_fontStyle failed: %08x\n", hres);
3217     ok(!strcmp_wa(str, "normal"), "get_fontStyle returned %s\n", wine_dbgstr_w(str));
3218     SysFreeString(str);
3219
3220     hres = IHTMLCurrentStyle_get_backgroundImage(current_style, &str);
3221     ok(hres == S_OK, "get_backgroundImage failed: %08x\n", hres);
3222     ok(!strcmp_wa(str, "none"), "get_backgroundImage returned %s\n", wine_dbgstr_w(str));
3223     SysFreeString(str);
3224
3225     hres = IHTMLCurrentStyle_get_fontVariant(current_style, &str);
3226     ok(hres == S_OK, "get_fontVariant failed: %08x\n", hres);
3227     ok(!strcmp_wa(str, "normal"), "get_fontVariant returned %s\n", wine_dbgstr_w(str));
3228     SysFreeString(str);
3229
3230     hres = IHTMLCurrentStyle_get_borderTopStyle(current_style, &str);
3231     ok(hres == S_OK, "get_borderTopStyle failed: %08x\n", hres);
3232     ok(!strcmp_wa(str, "none"), "get_borderTopStyle returned %s\n", wine_dbgstr_w(str));
3233     SysFreeString(str);
3234
3235     hres = IHTMLCurrentStyle_get_borderRightStyle(current_style, &str);
3236     ok(hres == S_OK, "get_borderRightStyle failed: %08x\n", hres);
3237     ok(!strcmp_wa(str, "none"), "get_borderRightStyle returned %s\n", wine_dbgstr_w(str));
3238     SysFreeString(str);
3239
3240     hres = IHTMLCurrentStyle_get_borderBottomStyle(current_style, &str);
3241     ok(hres == S_OK, "get_borderBottomStyle failed: %08x\n", hres);
3242     ok(!strcmp_wa(str, "none"), "get_borderBottomStyle returned %s\n", wine_dbgstr_w(str));
3243     SysFreeString(str);
3244
3245     hres = IHTMLCurrentStyle_get_borderLeftStyle(current_style, &str);
3246     ok(hres == S_OK, "get_borderLeftStyle failed: %08x\n", hres);
3247     ok(!strcmp_wa(str, "none"), "get_borderLeftStyle returned %s\n", wine_dbgstr_w(str));
3248     SysFreeString(str);
3249
3250     hres = IHTMLCurrentStyle_get_textAlign(current_style, &str);
3251     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
3252     ok(!strcmp_wa(str, "center"), "get_textAlign returned %s\n", wine_dbgstr_w(str));
3253     SysFreeString(str);
3254
3255     hres = IHTMLCurrentStyle_get_textDecoration(current_style, &str);
3256     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3257     ok(!strcmp_wa(str, "none"), "get_textDecoration returned %s\n", wine_dbgstr_w(str));
3258     SysFreeString(str);
3259
3260     hres = IHTMLCurrentStyle_get_cursor(current_style, &str);
3261     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
3262     ok(!strcmp_wa(str, "default"), "get_cursor returned %s\n", wine_dbgstr_w(str));
3263     SysFreeString(str);
3264
3265     hres = IHTMLCurrentStyle_get_backgroundRepeat(current_style, &str);
3266     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
3267     ok(!strcmp_wa(str, "repeat"), "get_backgroundRepeat returned %s\n", wine_dbgstr_w(str));
3268     SysFreeString(str);
3269
3270     hres = IHTMLCurrentStyle_get_borderColor(current_style, &str);
3271     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
3272     SysFreeString(str);
3273
3274     hres = IHTMLCurrentStyle_get_borderStyle(current_style, &str);
3275     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
3276     SysFreeString(str);
3277
3278     hres = IHTMLCurrentStyle_get_visibility(current_style, &str);
3279     ok(hres == S_OK, "get_visibility failed: %08x\n", hres);
3280     SysFreeString(str);
3281
3282     hres = IHTMLCurrentStyle_get_overflow(current_style, &str);
3283     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
3284     SysFreeString(str);
3285
3286     hres = IHTMLCurrentStyle_get_borderWidth(current_style, &str);
3287     ok(hres == S_OK, "get_borderWidth failed: %08x\n", hres);
3288     SysFreeString(str);
3289
3290     hres = IHTMLCurrentStyle_get_margin(current_style, &str);
3291     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3292     SysFreeString(str);
3293
3294     hres = IHTMLCurrentStyle_get_fontWeight(current_style, &v);
3295     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3296     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
3297     ok( V_I4(&v) == 400, "expect 400 got (%d)\n", V_I4(&v));
3298     VariantClear(&v);
3299
3300     hres = IHTMLCurrentStyle_get_fontSize(current_style, &v);
3301     ok(hres == S_OK, "get_fontSize failed: %08x\n", hres);
3302     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3303     VariantClear(&v);
3304
3305     hres = IHTMLCurrentStyle_get_left(current_style, &v);
3306     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3307     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3308     VariantClear(&v);
3309
3310     hres = IHTMLCurrentStyle_get_top(current_style, &v);
3311     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3312     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3313     VariantClear(&v);
3314
3315     hres = IHTMLCurrentStyle_get_width(current_style, &v);
3316     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3317     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3318     VariantClear(&v);
3319
3320     hres = IHTMLCurrentStyle_get_height(current_style, &v);
3321     ok(hres == S_OK, "get_height failed: %08x\n", hres);
3322     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3323     VariantClear(&v);
3324
3325     hres = IHTMLCurrentStyle_get_paddingLeft(current_style, &v);
3326     ok(hres == S_OK, "get_paddingLeft failed: %08x\n", hres);
3327     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3328     VariantClear(&v);
3329
3330     hres = IHTMLCurrentStyle_get_zIndex(current_style, &v);
3331     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
3332     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
3333     ok( V_I4(&v) == 1, "expect 1 got (%d)\n", V_I4(&v));
3334     VariantClear(&v);
3335
3336     hres = IHTMLCurrentStyle_get_verticalAlign(current_style, &v);
3337     ok(hres == S_OK, "get_verticalAlign failed: %08x\n", hres);
3338     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3339     ok(!strcmp_wa(V_BSTR(&v), "middle"), "get_verticalAlign returned %s\n", wine_dbgstr_w(V_BSTR(&v)));
3340     VariantClear(&v);
3341
3342     hres = IHTMLCurrentStyle_get_marginRight(current_style, &v);
3343     ok(hres == S_OK, "get_marginRight failed: %08x\n", hres);
3344     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3345     VariantClear(&v);
3346
3347     hres = IHTMLCurrentStyle_get_marginLeft(current_style, &v);
3348     ok(hres == S_OK, "get_marginLeft failed: %08x\n", hres);
3349     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3350     VariantClear(&v);
3351
3352     hres = IHTMLCurrentStyle_get_borderLeftWidth(current_style, &v);
3353     ok(hres == S_OK, "get_borderLeftWidth failed: %08x\n", hres);
3354     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3355     VariantClear(&v);
3356
3357     V_BSTR(&v) = NULL;
3358     hres = IHTMLCurrentStyle_get_borderRightWidth(current_style, &v);
3359     ok(hres == S_OK, "get_borderRightWidth failed: %08x\n", hres);
3360     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3361     VariantClear(&v);
3362
3363     hres = IHTMLCurrentStyle_get_borderBottomWidth(current_style, &v);
3364     ok(hres == S_OK, "get_borderBottomWidth failed: %08x\n", hres);
3365     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3366     VariantClear(&v);
3367
3368     hres = IHTMLCurrentStyle_get_borderTopWidth(current_style, &v);
3369     ok(hres == S_OK, "get_borderTopWidth failed: %08x\n", hres);
3370     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3371     VariantClear(&v);
3372
3373     hres = IHTMLCurrentStyle_get_color(current_style, &v);
3374     ok(hres == S_OK, "get_color failed: %08x\n", hres);
3375     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3376     VariantClear(&v);
3377
3378     hres = IHTMLCurrentStyle_get_backgroundColor(current_style, &v);
3379     ok(hres == S_OK, "get_backgroundColor failed: %08x\n", hres);
3380     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3381     VariantClear(&v);
3382
3383     hres = IHTMLCurrentStyle_get_borderLeftColor(current_style, &v);
3384     ok(hres == S_OK, "get_borderLeftColor failed: %08x\n", hres);
3385     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3386     VariantClear(&v);
3387
3388     hres = IHTMLCurrentStyle_get_borderTopColor(current_style, &v);
3389     ok(hres == S_OK, "get_borderTopColor failed: %08x\n", hres);
3390     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3391     VariantClear(&v);
3392
3393     hres = IHTMLCurrentStyle_get_borderRightColor(current_style, &v);
3394     ok(hres == S_OK, "get_borderRightColor failed: %08x\n", hres);
3395     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3396     VariantClear(&v);
3397
3398     hres = IHTMLCurrentStyle_get_borderBottomColor(current_style, &v);
3399     ok(hres == S_OK, "get_borderBottomColor failed: %08x\n", hres);
3400     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3401     VariantClear(&v);
3402
3403     hres = IHTMLCurrentStyle_get_paddingTop(current_style, &v);
3404     ok(hres == S_OK, "get_paddingTop failed: %08x\n", hres);
3405     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3406     VariantClear(&v);
3407
3408     hres = IHTMLCurrentStyle_get_paddingRight(current_style, &v);
3409     ok(hres == S_OK, "get_paddingRight failed: %08x\n", hres);
3410     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3411     VariantClear(&v);
3412
3413     hres = IHTMLCurrentStyle_get_paddingBottom(current_style, &v);
3414     ok(hres == S_OK, "get_paddingRight failed: %08x\n", hres);
3415     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3416     VariantClear(&v);
3417
3418     hres = IHTMLCurrentStyle_get_letterSpacing(current_style, &v);
3419     ok(hres == S_OK, "get_letterSpacing failed: %08x\n", hres);
3420     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3421     VariantClear(&v);
3422
3423     hres = IHTMLCurrentStyle_get_marginTop(current_style, &v);
3424     ok(hres == S_OK, "get_marginTop failed: %08x\n", hres);
3425     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3426     VariantClear(&v);
3427
3428     hres = IHTMLCurrentStyle_get_marginBottom(current_style, &v);
3429     ok(hres == S_OK, "get_marginBottom failed: %08x\n", hres);
3430     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3431     VariantClear(&v);
3432
3433     hres = IHTMLCurrentStyle_get_right(current_style, &v);
3434     ok(hres == S_OK, "get_Right failed: %08x\n", hres);
3435     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3436     VariantClear(&v);
3437
3438     hres = IHTMLCurrentStyle_get_bottom(current_style, &v);
3439     ok(hres == S_OK, "get_bottom failed: %08x\n", hres);
3440     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3441     VariantClear(&v);
3442
3443     hres = IHTMLCurrentStyle_get_lineHeight(current_style, &v);
3444     ok(hres == S_OK, "get_lineHeight failed: %08x\n", hres);
3445     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3446     VariantClear(&v);
3447
3448     hres = IHTMLCurrentStyle_get_textIndent(current_style, &v);
3449     ok(hres == S_OK, "get_textIndent failed: %08x\n", hres);
3450     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3451     VariantClear(&v);
3452 }
3453
3454 static void test_style2(IHTMLStyle2 *style2)
3455 {
3456     VARIANT v;
3457     BSTR str;
3458     HRESULT hres;
3459
3460     str = (void*)0xdeadbeef;
3461     hres = IHTMLStyle2_get_position(style2, &str);
3462     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3463     ok(!str, "str != NULL\n");
3464
3465     str = a2bstr("absolute");
3466     hres = IHTMLStyle2_put_position(style2, str);
3467     ok(hres == S_OK, "put_position failed: %08x\n", hres);
3468     SysFreeString(str);
3469
3470     str = NULL;
3471     hres = IHTMLStyle2_get_position(style2, &str);
3472     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3473     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
3474     SysFreeString(str);
3475
3476     /* Test right */
3477     V_VT(&v) = VT_EMPTY;
3478     hres = IHTMLStyle2_get_right(style2, &v);
3479     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3480     ok(V_VT(&v) == VT_BSTR, "V_VT(right)=%d\n", V_VT(&v));
3481     ok(!V_BSTR(&v), "V_BSTR(right) != NULL\n");
3482     VariantClear(&v);
3483
3484     V_VT(&v) = VT_BSTR;
3485     V_BSTR(&v) = a2bstr("3px");
3486     hres = IHTMLStyle2_put_right(style2, v);
3487     ok(hres == S_OK, "put_right failed: %08x\n", hres);
3488     VariantClear(&v);
3489
3490     V_VT(&v) = VT_EMPTY;
3491     hres = IHTMLStyle2_get_right(style2, &v);
3492     ok(hres == S_OK, "get_right failed: %08x\n", hres);
3493     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3494     ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3495     VariantClear(&v);
3496 }
3497
3498 static void test_style3(IHTMLStyle3 *style3)
3499 {
3500     BSTR str;
3501     HRESULT hres;
3502
3503     str = (void*)0xdeadbeef;
3504     hres = IHTMLStyle3_get_wordWrap(style3, &str);
3505     ok(hres == S_OK, "get_wordWrap failed: %08x\n", hres);
3506     ok(!str, "str != NULL\n");
3507
3508     str = a2bstr("break-word");
3509     hres = IHTMLStyle3_put_wordWrap(style3, str);
3510     ok(hres == S_OK, "put_wordWrap failed: %08x\n", hres);
3511     SysFreeString(str);
3512
3513     str = NULL;
3514     hres = IHTMLStyle3_get_wordWrap(style3, &str);
3515     ok(hres == S_OK, "get_wordWrap failed: %08x\n", hres);
3516     ok(!strcmp_wa(str, "break-word"), "get_wordWrap returned %s\n", wine_dbgstr_w(str));
3517     SysFreeString(str);
3518 }
3519
3520 static void test_style4(IHTMLStyle4 *style4)
3521 {
3522     HRESULT hres;
3523     VARIANT v;
3524     VARIANT vdefault;
3525
3526     hres = IHTMLStyle4_get_minHeight(style4, &vdefault);
3527     ok(hres == S_OK, "get_minHeight failed: %08x\n", hres);
3528
3529     V_VT(&v) = VT_BSTR;
3530     V_BSTR(&v) = a2bstr("10px");
3531     hres = IHTMLStyle4_put_minHeight(style4, v);
3532     ok(hres == S_OK, "put_minHeight failed: %08x\n", hres);
3533     VariantClear(&v);
3534
3535     hres = IHTMLStyle4_get_minHeight(style4, &v);
3536     ok(hres == S_OK, "get_minHeight failed: %08x\n", hres);
3537     ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
3538     ok( !strcmp_wa(V_BSTR(&v), "10px"), "expect 10px got (%s)\n", wine_dbgstr_w(V_BSTR(&v)));
3539
3540     hres = IHTMLStyle4_put_minHeight(style4, vdefault);
3541     ok(hres == S_OK, "put_minHeight failed: %08x\n", hres);
3542     VariantClear(&vdefault);
3543 }
3544
3545 static void test_default_style(IHTMLStyle *style)
3546 {
3547     IHTMLStyle2 *style2;
3548     IHTMLStyle3 *style3;
3549     IHTMLStyle4 *style4;
3550     VARIANT_BOOL b;
3551     VARIANT v;
3552     BSTR str;
3553     HRESULT hres;
3554     float f;
3555     BSTR sOverflowDefault;
3556     BSTR sDefault;
3557     VARIANT vDefault;
3558
3559     test_disp((IUnknown*)style, &DIID_DispHTMLStyle, "[object]");
3560     test_ifaces((IUnknown*)style, style_iids);
3561
3562     test_style_csstext(style, NULL);
3563
3564     hres = IHTMLStyle_get_position(style, &str);
3565     ok(hres == S_OK, "get_position failed: %08x\n", hres);
3566     ok(!str, "str=%s\n", wine_dbgstr_w(str));
3567
3568     V_VT(&v) = VT_NULL;
3569     hres = IHTMLStyle_get_marginRight(style, &v);
3570     ok(hres == S_OK, "get_marginRight failed: %08x\n", hres);
3571     ok(V_VT(&v) == VT_BSTR, "V_VT(marginRight) = %d\n", V_VT(&v));
3572     ok(!V_BSTR(&v), "V_BSTR(marginRight) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3573
3574     V_VT(&v) = VT_NULL;
3575     hres = IHTMLStyle_get_marginLeft(style, &v);
3576     ok(hres == S_OK, "get_marginLeft failed: %08x\n", hres);
3577     ok(V_VT(&v) == VT_BSTR, "V_VT(marginLeft) = %d\n", V_VT(&v));
3578     ok(!V_BSTR(&v), "V_BSTR(marginLeft) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3579
3580     str = (void*)0xdeadbeef;
3581     hres = IHTMLStyle_get_fontFamily(style, &str);
3582     ok(hres == S_OK, "get_fontFamily failed: %08x\n", hres);
3583     ok(!str, "fontFamily = %s\n", wine_dbgstr_w(str));
3584
3585     str = (void*)0xdeadbeef;
3586     hres = IHTMLStyle_get_fontWeight(style, &str);
3587     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3588     ok(!str, "fontWeight = %s\n", wine_dbgstr_w(str));
3589
3590     hres = IHTMLStyle_get_fontWeight(style, &sDefault);
3591     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3592
3593     str = a2bstr("test");
3594     hres = IHTMLStyle_put_fontWeight(style, str);
3595     ok(hres == E_INVALIDARG, "put_fontWeight failed: %08x\n", hres);
3596     SysFreeString(str);
3597
3598     str = a2bstr("bold");
3599     hres = IHTMLStyle_put_fontWeight(style, str);
3600     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3601     SysFreeString(str);
3602
3603     str = a2bstr("bolder");
3604     hres = IHTMLStyle_put_fontWeight(style, str);
3605     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3606     SysFreeString(str);
3607
3608     str = a2bstr("lighter");
3609     hres = IHTMLStyle_put_fontWeight(style, str);
3610     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3611     SysFreeString(str);
3612
3613     str = a2bstr("100");
3614     hres = IHTMLStyle_put_fontWeight(style, str);
3615     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3616     SysFreeString(str);
3617
3618     str = a2bstr("200");
3619     hres = IHTMLStyle_put_fontWeight(style, str);
3620     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3621     SysFreeString(str);
3622
3623     str = a2bstr("300");
3624     hres = IHTMLStyle_put_fontWeight(style, str);
3625     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3626     SysFreeString(str);
3627
3628     str = a2bstr("400");
3629     hres = IHTMLStyle_put_fontWeight(style, str);
3630     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3631     SysFreeString(str);
3632
3633     str = a2bstr("500");
3634     hres = IHTMLStyle_put_fontWeight(style, str);
3635     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3636     SysFreeString(str);
3637
3638     str = a2bstr("600");
3639     hres = IHTMLStyle_put_fontWeight(style, str);
3640     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3641     SysFreeString(str);
3642
3643     str = a2bstr("700");
3644     hres = IHTMLStyle_put_fontWeight(style, str);
3645     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3646     SysFreeString(str);
3647
3648     str = a2bstr("800");
3649     hres = IHTMLStyle_put_fontWeight(style, str);
3650     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3651     SysFreeString(str);
3652
3653     str = a2bstr("900");
3654     hres = IHTMLStyle_put_fontWeight(style, str);
3655     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3656     SysFreeString(str);
3657
3658     hres = IHTMLStyle_get_fontWeight(style, &str);
3659     ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres);
3660     ok(!strcmp_wa(str, "900"), "str != style900\n");
3661     SysFreeString(str);
3662
3663     hres = IHTMLStyle_put_fontWeight(style, sDefault);
3664     ok(hres == S_OK, "put_fontWeight failed: %08x\n", hres);
3665     SysFreeString(sDefault);
3666
3667     /* font Variant */
3668     hres = IHTMLStyle_get_fontVariant(style, NULL);
3669     ok(hres == E_INVALIDARG, "get_fontVariant failed: %08x\n", hres);
3670
3671     hres = IHTMLStyle_get_fontVariant(style, &sDefault);
3672     ok(hres == S_OK, "get_fontVariant failed: %08x\n", hres);
3673
3674     str = a2bstr("test");
3675     hres = IHTMLStyle_put_fontVariant(style, str);
3676     ok(hres == E_INVALIDARG, "fontVariant failed: %08x\n", hres);
3677     SysFreeString(str);
3678
3679     str = a2bstr("small-caps");
3680     hres = IHTMLStyle_put_fontVariant(style, str);
3681     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3682     SysFreeString(str);
3683
3684     str = a2bstr("normal");
3685     hres = IHTMLStyle_put_fontVariant(style, str);
3686     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3687     SysFreeString(str);
3688
3689     hres = IHTMLStyle_put_fontVariant(style, sDefault);
3690     ok(hres == S_OK, "fontVariant failed: %08x\n", hres);
3691     SysFreeString(sDefault);
3692
3693     str = (void*)0xdeadbeef;
3694     hres = IHTMLStyle_get_display(style, &str);
3695     ok(hres == S_OK, "get_display failed: %08x\n", hres);
3696     ok(!str, "display = %s\n", wine_dbgstr_w(str));
3697
3698     str = (void*)0xdeadbeef;
3699     hres = IHTMLStyle_get_visibility(style, &str);
3700     ok(hres == S_OK, "get_visibility failed: %08x\n", hres);
3701     ok(!str, "visibility = %s\n", wine_dbgstr_w(str));
3702
3703     V_VT(&v) = VT_NULL;
3704     hres = IHTMLStyle_get_fontSize(style, &v);
3705     ok(hres == S_OK, "get_fontSize failed: %08x\n", hres);
3706     ok(V_VT(&v) == VT_BSTR, "V_VT(fontSize) = %d\n", V_VT(&v));
3707     ok(!V_BSTR(&v), "V_BSTR(fontSize) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3708
3709     V_VT(&v) = VT_NULL;
3710     hres = IHTMLStyle_get_color(style, &v);
3711     ok(hres == S_OK, "get_color failed: %08x\n", hres);
3712     ok(V_VT(&v) == VT_BSTR, "V_VT(color) = %d\n", V_VT(&v));
3713     ok(!V_BSTR(&v), "V_BSTR(color) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3714
3715     b = 0xfefe;
3716     hres = IHTMLStyle_get_textDecorationUnderline(style, &b);
3717     ok(hres == S_OK, "get_textDecorationUnderline failed: %08x\n", hres);
3718     ok(b == VARIANT_FALSE, "textDecorationUnderline = %x\n", b);
3719
3720     hres = IHTMLStyle_put_textDecorationUnderline(style, VARIANT_TRUE);
3721     ok(hres == S_OK, "put_textDecorationUnderline failed: %08x\n", hres);
3722     ok(b == VARIANT_FALSE, "textDecorationUnderline = %x\n", b);
3723
3724     hres = IHTMLStyle_get_textDecorationUnderline(style, &b);
3725     ok(hres == S_OK, "get_textDecorationUnderline failed: %08x\n", hres);
3726     ok(b == VARIANT_TRUE, "textDecorationUnderline = %x\n", b);
3727
3728     hres = IHTMLStyle_put_textDecorationUnderline(style, VARIANT_FALSE);
3729     ok(hres == S_OK, "put_textDecorationUnderline failed: %08x\n", hres);
3730
3731     b = 0xfefe;
3732     hres = IHTMLStyle_get_textDecorationLineThrough(style, &b);
3733     ok(hres == S_OK, "get_textDecorationLineThrough failed: %08x\n", hres);
3734     ok(b == VARIANT_FALSE, "textDecorationLineThrough = %x\n", b);
3735
3736     hres = IHTMLStyle_put_textDecorationLineThrough(style, VARIANT_TRUE);
3737     ok(hres == S_OK, "put_textDecorationLineThrough failed: %08x\n", hres);
3738     ok(b == VARIANT_FALSE, "textDecorationLineThrough = %x\n", b);
3739
3740     hres = IHTMLStyle_get_textDecorationLineThrough(style, &b);
3741     ok(hres == S_OK, "get_textDecorationLineThrough failed: %08x\n", hres);
3742     ok(b == VARIANT_TRUE, "textDecorationLineThrough = %x\n", b);
3743
3744     hres = IHTMLStyle_put_textDecorationLineThrough(style, VARIANT_FALSE);
3745     ok(hres == S_OK, "put_textDecorationLineThrough failed: %08x\n", hres);
3746
3747     b = 0xfefe;
3748     hres = IHTMLStyle_get_textDecorationNone(style, &b);
3749     ok(hres == S_OK, "get_textDecorationNone failed: %08x\n", hres);
3750     ok(b == VARIANT_FALSE, "textDecorationNone = %x\n", b);
3751
3752     hres = IHTMLStyle_put_textDecorationNone(style, VARIANT_TRUE);
3753     ok(hres == S_OK, "put_textDecorationNone failed: %08x\n", hres);
3754     ok(b == VARIANT_FALSE, "textDecorationNone = %x\n", b);
3755
3756     hres = IHTMLStyle_get_textDecorationNone(style, &b);
3757     ok(hres == S_OK, "get_textDecorationNone failed: %08x\n", hres);
3758     ok(b == VARIANT_TRUE, "textDecorationNone = %x\n", b);
3759
3760     hres = IHTMLStyle_put_textDecorationNone(style, VARIANT_FALSE);
3761     ok(hres == S_OK, "put_textDecorationNone failed: %08x\n", hres);
3762
3763     b = 0xfefe;
3764     hres = IHTMLStyle_get_textDecorationOverline(style, &b);
3765     ok(hres == S_OK, "get_textDecorationOverline failed: %08x\n", hres);
3766     ok(b == VARIANT_FALSE, "textDecorationOverline = %x\n", b);
3767
3768     hres = IHTMLStyle_put_textDecorationOverline(style, VARIANT_TRUE);
3769     ok(hres == S_OK, "put_textDecorationOverline failed: %08x\n", hres);
3770     ok(b == VARIANT_FALSE, "textDecorationOverline = %x\n", b);
3771
3772     hres = IHTMLStyle_get_textDecorationOverline(style, &b);
3773     ok(hres == S_OK, "get_textDecorationOverline failed: %08x\n", hres);
3774     ok(b == VARIANT_TRUE, "textDecorationOverline = %x\n", b);
3775
3776     hres = IHTMLStyle_put_textDecorationOverline(style, VARIANT_FALSE);
3777     ok(hres == S_OK, "put_textDecorationOverline failed: %08x\n", hres);
3778
3779     b = 0xfefe;
3780     hres = IHTMLStyle_get_textDecorationBlink(style, &b);
3781     ok(hres == S_OK, "get_textDecorationBlink failed: %08x\n", hres);
3782     ok(b == VARIANT_FALSE, "textDecorationBlink = %x\n", b);
3783
3784     hres = IHTMLStyle_put_textDecorationBlink(style, VARIANT_TRUE);
3785     ok(hres == S_OK, "put_textDecorationBlink failed: %08x\n", hres);
3786     ok(b == VARIANT_FALSE, "textDecorationBlink = %x\n", b);
3787
3788     hres = IHTMLStyle_get_textDecorationBlink(style, &b);
3789     ok(hres == S_OK, "get_textDecorationBlink failed: %08x\n", hres);
3790     ok(b == VARIANT_TRUE, "textDecorationBlink = %x\n", b);
3791
3792     hres = IHTMLStyle_put_textDecorationBlink(style, VARIANT_FALSE);
3793     ok(hres == S_OK, "textDecorationBlink failed: %08x\n", hres);
3794
3795     hres = IHTMLStyle_get_textDecoration(style, &sDefault);
3796     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3797
3798     str = a2bstr("invalid");
3799     hres = IHTMLStyle_put_textDecoration(style, str);
3800     ok(hres == E_INVALIDARG, "put_textDecoration failed: %08x\n", hres);
3801     SysFreeString(str);
3802
3803     str = a2bstr("none");
3804     hres = IHTMLStyle_put_textDecoration(style, str);
3805     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3806     SysFreeString(str);
3807
3808     str = a2bstr("underline");
3809     hres = IHTMLStyle_put_textDecoration(style, str);
3810     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3811     SysFreeString(str);
3812
3813     str = a2bstr("overline");
3814     hres = IHTMLStyle_put_textDecoration(style, str);
3815     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3816     SysFreeString(str);
3817
3818     str = a2bstr("line-through");
3819     hres = IHTMLStyle_put_textDecoration(style, str);
3820     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3821     SysFreeString(str);
3822
3823     str = a2bstr("blink");
3824     hres = IHTMLStyle_put_textDecoration(style, str);
3825     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3826     SysFreeString(str);
3827
3828     hres = IHTMLStyle_get_textDecoration(style, &str);
3829     ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres);
3830     ok(!strcmp_wa(str, "blink"), "str != blink\n");
3831     SysFreeString(str);
3832
3833     hres = IHTMLStyle_put_textDecoration(style, sDefault);
3834     ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres);
3835     SysFreeString(sDefault);
3836
3837     hres = IHTMLStyle_get_posWidth(style, NULL);
3838     ok(hres == E_POINTER, "get_posWidth failed: %08x\n", hres);
3839
3840     hres = IHTMLStyle_get_posWidth(style, &f);
3841     ok(hres == S_OK, "get_posWidth failed: %08x\n", hres);
3842     ok(f == 0.0f, "f = %f\n", f);
3843
3844     V_VT(&v) = VT_EMPTY;
3845     hres = IHTMLStyle_get_width(style, &v);
3846     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3847     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3848     ok(!V_BSTR(&v), "V_BSTR(v)=%p\n", V_BSTR(&v));
3849
3850     hres = IHTMLStyle_put_posWidth(style, 2.2);
3851     ok(hres == S_OK, "put_posWidth failed: %08x\n", hres);
3852
3853     hres = IHTMLStyle_get_posWidth(style, &f);
3854     ok(hres == S_OK, "get_posWidth failed: %08x\n", hres);
3855     ok(f == 2.0f ||
3856        f == 2.2f, /* IE8 */
3857        "f = %f\n", f);
3858
3859     V_VT(&v) = VT_BSTR;
3860     V_BSTR(&v) = a2bstr("auto");
3861     hres = IHTMLStyle_put_width(style, v);
3862     ok(hres == S_OK, "put_width failed: %08x\n", hres);
3863     VariantClear(&v);
3864
3865     V_VT(&v) = VT_EMPTY;
3866     hres = IHTMLStyle_get_width(style, &v);
3867     ok(hres == S_OK, "get_width failed: %08x\n", hres);
3868     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3869     ok(!strcmp_wa(V_BSTR(&v), "auto"), "V_BSTR(v)=%s\n", wine_dbgstr_w(V_BSTR(&v)));
3870     VariantClear(&v);
3871
3872     /* margin tests */
3873     str = (void*)0xdeadbeef;
3874     hres = IHTMLStyle_get_margin(style, &str);
3875     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3876     ok(!str, "margin = %s\n", wine_dbgstr_w(str));
3877
3878     str = a2bstr("1");
3879     hres = IHTMLStyle_put_margin(style, str);
3880     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
3881     SysFreeString(str);
3882
3883     hres = IHTMLStyle_get_margin(style, &str);
3884     ok(hres == S_OK, "get_margin failed: %08x\n", hres);
3885     ok(!strcmp_wa(str, "1px"), "margin = %s\n", wine_dbgstr_w(str));
3886
3887     hres = IHTMLStyle_put_margin(style, NULL);
3888     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
3889
3890     str = (void*)0xdeadbeef;
3891     hres = IHTMLStyle_get_marginTop(style, &v);
3892     ok(hres == S_OK, "get_marginTop failed: %08x\n", hres);
3893     ok(V_VT(&v) == VT_BSTR, "V_VT(marginTop) = %d\n", V_VT(&v));
3894     ok(!V_BSTR(&v), "V_BSTR(marginTop) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3895
3896     V_VT(&v) = VT_BSTR;
3897     V_BSTR(&v) = a2bstr("6px");
3898     hres = IHTMLStyle_put_marginTop(style, v);
3899     SysFreeString(V_BSTR(&v));
3900     ok(hres == S_OK, "put_marginTop failed: %08x\n", hres);
3901
3902     str = (void*)0xdeadbeef;
3903     hres = IHTMLStyle_get_marginTop(style, &v);
3904     ok(hres == S_OK, "get_marginTop failed: %08x\n", hres);
3905     ok(V_VT(&v) == VT_BSTR, "V_VT(marginTop) = %d\n", V_VT(&v));
3906     ok(!strcmp_wa(V_BSTR(&v), "6px"), "V_BSTR(marginTop) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3907
3908     str = NULL;
3909     hres = IHTMLStyle_get_border(style, &str);
3910     ok(hres == S_OK, "get_border failed: %08x\n", hres);
3911     ok(!str || !*str, "str is not empty\n");
3912     SysFreeString(str);
3913
3914     str = a2bstr("1px");
3915     hres = IHTMLStyle_put_border(style, str);
3916     ok(hres == S_OK, "put_border failed: %08x\n", hres);
3917     SysFreeString(str);
3918
3919     V_VT(&v) = VT_EMPTY;
3920     hres = IHTMLStyle_get_left(style, &v);
3921     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3922     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3923     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3924     VariantClear(&v);
3925
3926     /* Test posLeft */
3927     hres = IHTMLStyle_get_posLeft(style, NULL);
3928     ok(hres == E_POINTER, "get_posLeft failed: %08x\n", hres);
3929
3930     f = 1.0f;
3931     hres = IHTMLStyle_get_posLeft(style, &f);
3932     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3933     ok(f == 0.0, "expected 0.0 got %f\n", f);
3934
3935     hres = IHTMLStyle_put_posLeft(style, 4.9f);
3936     ok(hres == S_OK, "put_posLeft failed: %08x\n", hres);
3937
3938     hres = IHTMLStyle_get_posLeft(style, &f);
3939     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3940     ok(f == 4.0 ||
3941        f == 4.9f, /* IE8 */
3942        "expected 4.0 or 4.9 (IE8) got %f\n", f);
3943
3944     /* Ensure left is updated correctly. */
3945     V_VT(&v) = VT_EMPTY;
3946     hres = IHTMLStyle_get_left(style, &v);
3947     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3948     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3949     ok(!strcmp_wa(V_BSTR(&v), "4px") ||
3950        !strcmp_wa(V_BSTR(&v), "4.9px"), /* IE8 */
3951        "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3952     VariantClear(&v);
3953
3954     /* Test left */
3955     V_VT(&v) = VT_BSTR;
3956     V_BSTR(&v) = a2bstr("3px");
3957     hres = IHTMLStyle_put_left(style, v);
3958     ok(hres == S_OK, "put_left failed: %08x\n", hres);
3959     VariantClear(&v);
3960
3961     hres = IHTMLStyle_get_posLeft(style, &f);
3962     ok(hres == S_OK, "get_posLeft failed: %08x\n", hres);
3963     ok(f == 3.0, "expected 3.0 got %f\n", f);
3964
3965     V_VT(&v) = VT_EMPTY;
3966     hres = IHTMLStyle_get_left(style, &v);
3967     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3968     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3969     ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
3970     VariantClear(&v);
3971
3972     V_VT(&v) = VT_NULL;
3973     hres = IHTMLStyle_put_left(style, v);
3974     ok(hres == S_OK, "put_left failed: %08x\n", hres);
3975
3976     V_VT(&v) = VT_EMPTY;
3977     hres = IHTMLStyle_get_left(style, &v);
3978     ok(hres == S_OK, "get_left failed: %08x\n", hres);
3979     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3980     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3981     VariantClear(&v);
3982
3983     V_VT(&v) = VT_EMPTY;
3984     hres = IHTMLStyle_get_top(style, &v);
3985     ok(hres == S_OK, "get_top failed: %08x\n", hres);
3986     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
3987     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
3988     VariantClear(&v);
3989
3990     /* Test posTop */
3991     hres = IHTMLStyle_get_posTop(style, NULL);
3992     ok(hres == E_POINTER, "get_posTop failed: %08x\n", hres);
3993
3994     f = 1.0f;
3995     hres = IHTMLStyle_get_posTop(style, &f);
3996     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
3997     ok(f == 0.0, "expected 0.0 got %f\n", f);
3998
3999     hres = IHTMLStyle_put_posTop(style, 4.9f);
4000     ok(hres == S_OK, "put_posTop failed: %08x\n", hres);
4001
4002     hres = IHTMLStyle_get_posTop(style, &f);
4003     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
4004     ok(f == 4.0 ||
4005        f == 4.9f, /* IE8 */
4006        "expected 4.0 or 4.9 (IE8) got %f\n", f);
4007
4008     V_VT(&v) = VT_BSTR;
4009     V_BSTR(&v) = a2bstr("3px");
4010     hres = IHTMLStyle_put_top(style, v);
4011     ok(hres == S_OK, "put_top failed: %08x\n", hres);
4012     VariantClear(&v);
4013
4014     V_VT(&v) = VT_EMPTY;
4015     hres = IHTMLStyle_get_top(style, &v);
4016     ok(hres == S_OK, "get_top failed: %08x\n", hres);
4017     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4018     ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4019     VariantClear(&v);
4020
4021     hres = IHTMLStyle_get_posTop(style, &f);
4022     ok(hres == S_OK, "get_posTop failed: %08x\n", hres);
4023     ok(f == 3.0, "expected 3.0 got %f\n", f);
4024
4025     V_VT(&v) = VT_NULL;
4026     hres = IHTMLStyle_put_top(style, v);
4027     ok(hres == S_OK, "put_top failed: %08x\n", hres);
4028
4029     V_VT(&v) = VT_EMPTY;
4030     hres = IHTMLStyle_get_top(style, &v);
4031     ok(hres == S_OK, "get_top failed: %08x\n", hres);
4032     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4033     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
4034     VariantClear(&v);
4035
4036     /* Test posHeight */
4037     hres = IHTMLStyle_get_posHeight(style, NULL);
4038     ok(hres == E_POINTER, "get_posHeight failed: %08x\n", hres);
4039
4040     V_VT(&v) = VT_EMPTY;
4041     hres = IHTMLStyle_get_height(style, &v);
4042     ok(hres == S_OK, "get_height failed: %08x\n", hres);
4043     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4044     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
4045     VariantClear(&v);
4046
4047     f = 1.0f;
4048     hres = IHTMLStyle_get_posHeight(style, &f);
4049     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
4050     ok(f == 0.0, "expected 0.0 got %f\n", f);
4051
4052     hres = IHTMLStyle_put_posHeight(style, 4.9f);
4053     ok(hres == S_OK, "put_posHeight failed: %08x\n", hres);
4054
4055     hres = IHTMLStyle_get_posHeight(style, &f);
4056     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
4057     ok(f == 4.0 ||
4058        f == 4.9f, /* IE8 */
4059        "expected 4.0 or 4.9 (IE8) got %f\n", f);
4060
4061     V_VT(&v) = VT_BSTR;
4062     V_BSTR(&v) = a2bstr("64px");
4063     hres = IHTMLStyle_put_height(style, v);
4064     ok(hres == S_OK, "put_height failed: %08x\n", hres);
4065     VariantClear(&v);
4066
4067     V_VT(&v) = VT_EMPTY;
4068     hres = IHTMLStyle_get_height(style, &v);
4069     ok(hres == S_OK, "get_height failed: %08x\n", hres);
4070     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4071     ok(!strcmp_wa(V_BSTR(&v), "64px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4072     VariantClear(&v);
4073
4074     hres = IHTMLStyle_get_posHeight(style, &f);
4075     ok(hres == S_OK, "get_posHeight failed: %08x\n", hres);
4076     ok(f == 64.0, "expected 64.0 got %f\n", f);
4077
4078     str = (void*)0xdeadbeef;
4079     hres = IHTMLStyle_get_cursor(style, &str);
4080     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
4081     ok(!str, "get_cursor != NULL\n");
4082     SysFreeString(str);
4083
4084     str = a2bstr("default");
4085     hres = IHTMLStyle_put_cursor(style, str);
4086     ok(hres == S_OK, "put_cursor failed: %08x\n", hres);
4087     SysFreeString(str);
4088
4089     str = NULL;
4090     hres = IHTMLStyle_get_cursor(style, &str);
4091     ok(hres == S_OK, "get_cursor failed: %08x\n", hres);
4092     ok(!strcmp_wa(str, "default"), "get_cursor returned %s\n", wine_dbgstr_w(str));
4093     SysFreeString(str);
4094
4095     V_VT(&v) = VT_EMPTY;
4096     hres = IHTMLStyle_get_verticalAlign(style, &v);
4097     ok(hres == S_OK, "get_vertivalAlign failed: %08x\n", hres);
4098     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4099     ok(!V_BSTR(&v), "V_BSTR(v) != NULL\n");
4100     VariantClear(&v);
4101
4102     V_VT(&v) = VT_BSTR;
4103     V_BSTR(&v) = a2bstr("middle");
4104     hres = IHTMLStyle_put_verticalAlign(style, v);
4105     ok(hres == S_OK, "put_vertivalAlign failed: %08x\n", hres);
4106     VariantClear(&v);
4107
4108     V_VT(&v) = VT_EMPTY;
4109     hres = IHTMLStyle_get_verticalAlign(style, &v);
4110     ok(hres == S_OK, "get_verticalAlign failed: %08x\n", hres);
4111     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4112     ok(!strcmp_wa(V_BSTR(&v), "middle"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4113     VariantClear(&v);
4114
4115     str = (void*)0xdeadbeef;
4116     hres = IHTMLStyle_get_textAlign(style, &str);
4117     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
4118     ok(!str, "textAlign != NULL\n");
4119
4120     str = a2bstr("center");
4121     hres = IHTMLStyle_put_textAlign(style, str);
4122     ok(hres == S_OK, "put_textAlign failed: %08x\n", hres);
4123     SysFreeString(str);
4124
4125     str = NULL;
4126     hres = IHTMLStyle_get_textAlign(style, &str);
4127     ok(hres == S_OK, "get_textAlign failed: %08x\n", hres);
4128     ok(!strcmp_wa(str, "center"), "textAlign = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4129     SysFreeString(str);
4130
4131     str = (void*)0xdeadbeef;
4132     hres = IHTMLStyle_get_filter(style, &str);
4133     ok(hres == S_OK, "get_filter failed: %08x\n", hres);
4134     ok(!str, "filter != NULL\n");
4135
4136     str = a2bstr("alpha(opacity=100)");
4137     hres = IHTMLStyle_put_filter(style, str);
4138     ok(hres == S_OK, "put_filter failed: %08x\n", hres);
4139     SysFreeString(str);
4140
4141     V_VT(&v) = VT_EMPTY;
4142     hres = IHTMLStyle_get_zIndex(style, &v);
4143     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
4144     ok(V_VT(&v) == VT_I4, "V_VT(v)=%d\n", V_VT(&v));
4145     ok(!V_I4(&v), "V_I4(v) != 0\n");
4146     VariantClear(&v);
4147
4148     V_VT(&v) = VT_BSTR;
4149     V_BSTR(&v) = a2bstr("1");
4150     hres = IHTMLStyle_put_zIndex(style, v);
4151     ok(hres == S_OK, "put_zIndex failed: %08x\n", hres);
4152     VariantClear(&v);
4153
4154     V_VT(&v) = VT_EMPTY;
4155     hres = IHTMLStyle_get_zIndex(style, &v);
4156     ok(hres == S_OK, "get_zIndex failed: %08x\n", hres);
4157     ok(V_VT(&v) == VT_I4, "V_VT(v)=%d\n", V_VT(&v));
4158     ok(V_I4(&v) == 1, "V_I4(v) = %d\n", V_I4(&v));
4159     VariantClear(&v);
4160
4161     /* fontStyle */
4162     hres = IHTMLStyle_get_fontStyle(style, &sDefault);
4163     ok(hres == S_OK, "get_fontStyle failed: %08x\n", hres);
4164
4165     str = a2bstr("test");
4166     hres = IHTMLStyle_put_fontStyle(style, str);
4167     ok(hres == E_INVALIDARG, "put_fontStyle failed: %08x\n", hres);
4168     SysFreeString(str);
4169
4170     str = a2bstr("italic");
4171     hres = IHTMLStyle_put_fontStyle(style, str);
4172     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4173     SysFreeString(str);
4174
4175     str = a2bstr("oblique");
4176     hres = IHTMLStyle_put_fontStyle(style, str);
4177     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4178     SysFreeString(str);
4179
4180     str = a2bstr("normal");
4181     hres = IHTMLStyle_put_fontStyle(style, str);
4182     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4183     SysFreeString(str);
4184
4185     hres = IHTMLStyle_put_fontStyle(style, sDefault);
4186     ok(hres == S_OK, "put_fontStyle failed: %08x\n", hres);
4187     SysFreeString(sDefault);
4188
4189     /* overflow */
4190     hres = IHTMLStyle_get_overflow(style, NULL);
4191     ok(hres == E_INVALIDARG, "get_overflow failed: %08x\n", hres);
4192
4193     hres = IHTMLStyle_get_overflow(style, &sOverflowDefault);
4194     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
4195
4196     str = a2bstr("test");
4197     hres = IHTMLStyle_put_overflow(style, str);
4198     ok(hres == E_INVALIDARG, "put_overflow failed: %08x\n", hres);
4199     SysFreeString(str);
4200
4201     str = a2bstr("visible");
4202     hres = IHTMLStyle_put_overflow(style, str);
4203     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4204     SysFreeString(str);
4205
4206     str = a2bstr("scroll");
4207     hres = IHTMLStyle_put_overflow(style, str);
4208     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4209     SysFreeString(str);
4210
4211     str = a2bstr("hidden");
4212     hres = IHTMLStyle_put_overflow(style, str);
4213     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4214     SysFreeString(str);
4215
4216     str = a2bstr("auto");
4217     hres = IHTMLStyle_put_overflow(style, str);
4218     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4219     SysFreeString(str);
4220
4221     hres = IHTMLStyle_get_overflow(style, &str);
4222     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
4223     ok(!strcmp_wa(str, "auto"), "str=%s\n", wine_dbgstr_w(str));
4224     SysFreeString(str);
4225
4226     str = a2bstr("");
4227     hres = IHTMLStyle_put_overflow(style, str);
4228     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4229     SysFreeString(str);
4230
4231     hres = IHTMLStyle_get_overflow(style, &str);
4232     ok(hres == S_OK, "get_overflow failed: %08x\n", hres);
4233     ok(!str, "str=%s\n", wine_dbgstr_w(str));
4234     SysFreeString(str);
4235
4236     /* restore overflow default */
4237     hres = IHTMLStyle_put_overflow(style, sOverflowDefault);
4238     ok(hres == S_OK, "put_overflow failed: %08x\n", hres);
4239     SysFreeString(sOverflowDefault);
4240
4241     /* Attribute Tests*/
4242     hres = IHTMLStyle_getAttribute(style, NULL, 1, &v);
4243     ok(hres == E_INVALIDARG, "getAttribute failed: %08x\n", hres);
4244
4245     str = a2bstr("position");
4246     hres = IHTMLStyle_getAttribute(style, str, 1, NULL);
4247     ok(hres == E_INVALIDARG, "getAttribute failed: %08x\n", hres);
4248
4249     hres = IHTMLStyle_getAttribute(style, str, 1, &v);
4250     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
4251     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4252     VariantClear(&v);
4253
4254     hres = IHTMLStyle_setAttribute(style, NULL, v, 1);
4255     ok(hres == E_INVALIDARG, "setAttribute failed: %08x\n", hres);
4256
4257     V_VT(&v) = VT_BSTR;
4258     V_BSTR(&v) = a2bstr("absolute");
4259     hres = IHTMLStyle_setAttribute(style, str, v, 1);
4260     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
4261     VariantClear(&v);
4262
4263     hres = IHTMLStyle_getAttribute(style, str, 1, &v);
4264     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
4265     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4266     ok(!strcmp_wa(V_BSTR(&v), "absolute"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4267     VariantClear(&v);
4268
4269     V_VT(&v) = VT_BSTR;
4270     V_BSTR(&v) = NULL;
4271     hres = IHTMLStyle_setAttribute(style, str, v, 1);
4272     ok(hres == S_OK, "setAttribute failed: %08x\n", hres);
4273     VariantClear(&v);
4274
4275     SysFreeString(str);
4276
4277     str = a2bstr("borderLeftStyle");
4278     test_border_styles(style, str);
4279     SysFreeString(str);
4280
4281     str = a2bstr("borderbottomstyle");
4282     test_border_styles(style, str);
4283     SysFreeString(str);
4284
4285     str = a2bstr("borderrightstyle");
4286     test_border_styles(style, str);
4287     SysFreeString(str);
4288
4289     str = a2bstr("bordertopstyle");
4290     test_border_styles(style, str);
4291     SysFreeString(str);
4292
4293     hres = IHTMLStyle_get_borderStyle(style, &sDefault);
4294     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
4295
4296     str = a2bstr("none dotted dashed solid");
4297     hres = IHTMLStyle_put_borderStyle(style, str);
4298     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4299     SysFreeString(str);
4300
4301     str = a2bstr("none dotted dashed solid");
4302     hres = IHTMLStyle_get_borderStyle(style, &str);
4303     ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres);
4304     ok(!strcmp_wa(str, "none dotted dashed solid"),
4305         "expected (none dotted dashed solid) = (%s)\n", wine_dbgstr_w(V_BSTR(&v)));
4306     SysFreeString(str);
4307
4308     str = a2bstr("double groove ridge inset");
4309     hres = IHTMLStyle_put_borderStyle(style, str);
4310     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4311     SysFreeString(str);
4312
4313     str = a2bstr("window-inset outset ridge inset");
4314     hres = IHTMLStyle_put_borderStyle(style, str);
4315     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4316     SysFreeString(str);
4317
4318     str = a2bstr("window-inset");
4319     hres = IHTMLStyle_put_borderStyle(style, str);
4320     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4321     SysFreeString(str);
4322
4323     str = a2bstr("none none none none none");
4324     hres = IHTMLStyle_put_borderStyle(style, str);
4325     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4326     SysFreeString(str);
4327
4328     str = a2bstr("invalid none none none");
4329     hres = IHTMLStyle_put_borderStyle(style, str);
4330     ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres);
4331     SysFreeString(str);
4332
4333     str = a2bstr("none invalid none none");
4334     hres = IHTMLStyle_put_borderStyle(style, str);
4335     ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres);
4336     SysFreeString(str);
4337
4338     hres = IHTMLStyle_put_borderStyle(style, sDefault);
4339     ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres);
4340     SysFreeString(sDefault);
4341
4342     /* backgoundColor */
4343     hres = IHTMLStyle_get_backgroundColor(style, &v);
4344     ok(hres == S_OK, "get_backgroundColor: %08x\n", hres);
4345     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4346     ok(!V_BSTR(&v), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4347     VariantClear(&v);
4348
4349     /* PaddingLeft */
4350     hres = IHTMLStyle_get_paddingLeft(style, &vDefault);
4351     ok(hres == S_OK, "get_paddingLeft: %08x\n", hres);
4352
4353     V_VT(&v) = VT_BSTR;
4354     V_BSTR(&v) = a2bstr("10");
4355     hres = IHTMLStyle_put_paddingLeft(style, v);
4356     ok(hres == S_OK, "put_paddingLeft: %08x\n", hres);
4357     VariantClear(&v);
4358
4359     hres = IHTMLStyle_get_paddingLeft(style, &v);
4360     ok(hres == S_OK, "get_paddingLeft: %08x\n", hres);
4361     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expecte 10 = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4362
4363     hres = IHTMLStyle_put_paddingLeft(style, vDefault);
4364     ok(hres == S_OK, "put_paddingLeft: %08x\n", hres);
4365
4366     /* BackgroundRepeat */
4367     hres = IHTMLStyle_get_backgroundRepeat(style, &sDefault);
4368     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
4369
4370     str = a2bstr("invalid");
4371     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4372     ok(hres == E_INVALIDARG, "put_backgroundRepeat failed: %08x\n", hres);
4373     SysFreeString(str);
4374
4375     str = a2bstr("repeat");
4376     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4377     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4378     SysFreeString(str);
4379
4380     str = a2bstr("no-repeat");
4381     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4382     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4383     SysFreeString(str);
4384
4385     str = a2bstr("repeat-x");
4386     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4387     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4388     SysFreeString(str);
4389
4390     str = a2bstr("repeat-y");
4391     hres = IHTMLStyle_put_backgroundRepeat(style, str);
4392     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4393     SysFreeString(str);
4394
4395     hres = IHTMLStyle_get_backgroundRepeat(style, &str);
4396     ok(hres == S_OK, "get_backgroundRepeat failed: %08x\n", hres);
4397     ok(!strcmp_wa(str, "repeat-y"), "str=%s\n", wine_dbgstr_w(str));
4398     SysFreeString(str);
4399
4400     hres = IHTMLStyle_put_backgroundRepeat(style, sDefault);
4401     ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres);
4402     SysFreeString(sDefault);
4403
4404     /* BorderColor */
4405     hres = IHTMLStyle_get_borderColor(style, &sDefault);
4406     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
4407
4408     str = a2bstr("red green red blue");
4409     hres = IHTMLStyle_put_borderColor(style, str);
4410     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
4411     SysFreeString(str);
4412
4413     hres = IHTMLStyle_get_borderColor(style, &str);
4414     ok(hres == S_OK, "get_borderColor failed: %08x\n", hres);
4415     ok(!strcmp_wa(str, "red green red blue"), "str=%s\n", wine_dbgstr_w(str));
4416     SysFreeString(str);
4417
4418     hres = IHTMLStyle_put_borderColor(style, sDefault);
4419     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
4420     SysFreeString(sDefault);
4421
4422     /* BorderRight */
4423     hres = IHTMLStyle_get_borderRight(style, &sDefault);
4424     ok(hres == S_OK, "get_borderRight failed: %08x\n", hres);
4425
4426     str = a2bstr("thick dotted red");
4427     hres = IHTMLStyle_put_borderRight(style, str);
4428     ok(hres == S_OK, "put_borderRight failed: %08x\n", hres);
4429     SysFreeString(str);
4430
4431     /* IHTMLStyle_get_borderRight appears to have a bug where
4432         it returns the first letter of the color.  So we check
4433         each style individually.
4434      */
4435     V_BSTR(&v) = NULL;
4436     hres = IHTMLStyle_get_borderRightColor(style, &v);
4437     todo_wine ok(hres == S_OK, "get_borderRightColor failed: %08x\n", hres);
4438     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4439     VariantClear(&v);
4440
4441     V_BSTR(&v) = NULL;
4442     hres = IHTMLStyle_get_borderRightWidth(style, &v);
4443     ok(hres == S_OK, "get_borderRightWidth failed: %08x\n", hres);
4444     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4445     VariantClear(&v);
4446
4447     hres = IHTMLStyle_get_borderRightStyle(style, &str);
4448     ok(hres == S_OK, "get_borderRightStyle failed: %08x\n", hres);
4449     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4450     SysFreeString(str);
4451
4452     hres = IHTMLStyle_put_borderRight(style, sDefault);
4453     ok(hres == S_OK, "put_borderRight failed: %08x\n", hres);
4454     SysFreeString(sDefault);
4455
4456     /* BorderTop */
4457     hres = IHTMLStyle_get_borderTop(style, &sDefault);
4458     ok(hres == S_OK, "get_borderTop failed: %08x\n", hres);
4459
4460     str = a2bstr("thick dotted red");
4461     hres = IHTMLStyle_put_borderTop(style, str);
4462     ok(hres == S_OK, "put_borderTop failed: %08x\n", hres);
4463     SysFreeString(str);
4464
4465     /* IHTMLStyle_get_borderTop appears to have a bug where
4466         it returns the first letter of the color.  So we check
4467         each style individually.
4468      */
4469     V_BSTR(&v) = NULL;
4470     hres = IHTMLStyle_get_borderTopColor(style, &v);
4471     todo_wine ok(hres == S_OK, "get_borderTopColor failed: %08x\n", hres);
4472     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4473     VariantClear(&v);
4474
4475     V_BSTR(&v) = NULL;
4476     hres = IHTMLStyle_get_borderTopWidth(style, &v);
4477     ok(hres == S_OK, "get_borderTopWidth failed: %08x\n", hres);
4478     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4479     VariantClear(&v);
4480
4481     hres = IHTMLStyle_get_borderTopStyle(style, &str);
4482     ok(hres == S_OK, "get_borderTopStyle failed: %08x\n", hres);
4483     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4484     SysFreeString(str);
4485
4486     hres = IHTMLStyle_put_borderTop(style, sDefault);
4487     ok(hres == S_OK, "put_borderTop failed: %08x\n", hres);
4488     SysFreeString(sDefault);
4489
4490     /* BorderBottom */
4491     hres = IHTMLStyle_get_borderBottom(style, &sDefault);
4492     ok(hres == S_OK, "get_borderBottom failed: %08x\n", hres);
4493
4494     str = a2bstr("thick dotted red");
4495     hres = IHTMLStyle_put_borderBottom(style, str);
4496     ok(hres == S_OK, "put_borderBottom failed: %08x\n", hres);
4497     SysFreeString(str);
4498
4499     /* IHTMLStyle_get_borderBottom appears to have a bug where
4500         it returns the first letter of the color.  So we check
4501         each style individually.
4502      */
4503     V_BSTR(&v) = NULL;
4504     hres = IHTMLStyle_get_borderBottomColor(style, &v);
4505     todo_wine ok(hres == S_OK, "get_borderBottomColor failed: %08x\n", hres);
4506     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4507     VariantClear(&v);
4508
4509     V_BSTR(&v) = NULL;
4510     hres = IHTMLStyle_get_borderBottomWidth(style, &v);
4511     ok(hres == S_OK, "get_borderBottomWidth failed: %08x\n", hres);
4512     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4513     VariantClear(&v);
4514
4515     hres = IHTMLStyle_get_borderBottomStyle(style, &str);
4516     ok(hres == S_OK, "get_borderBottomStyle failed: %08x\n", hres);
4517     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4518     SysFreeString(str);
4519
4520     hres = IHTMLStyle_put_borderBottom(style, sDefault);
4521     ok(hres == S_OK, "put_borderBottom failed: %08x\n", hres);
4522     SysFreeString(sDefault);
4523
4524     /* BorderLeft */
4525     hres = IHTMLStyle_get_borderLeft(style, &sDefault);
4526     ok(hres == S_OK, "get_borderLeft failed: %08x\n", hres);
4527
4528     str = a2bstr("thick dotted red");
4529     hres = IHTMLStyle_put_borderLeft(style, str);
4530     ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres);
4531     SysFreeString(str);
4532
4533     /* IHTMLStyle_get_borderLeft appears to have a bug where
4534         it returns the first letter of the color.  So we check
4535         each style individually.
4536      */
4537     V_BSTR(&v) = NULL;
4538     hres = IHTMLStyle_get_borderLeftColor(style, &v);
4539     todo_wine ok(hres == S_OK, "get_borderLeftColor failed: %08x\n", hres);
4540     todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4541     VariantClear(&v);
4542
4543     V_BSTR(&v) = NULL;
4544     hres = IHTMLStyle_get_borderLeftWidth(style, &v);
4545     ok(hres == S_OK, "get_borderLeftWidth failed: %08x\n", hres);
4546     ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4547     VariantClear(&v);
4548
4549     hres = IHTMLStyle_get_borderLeftStyle(style, &str);
4550     ok(hres == S_OK, "get_borderLeftStyle failed: %08x\n", hres);
4551     ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
4552     SysFreeString(str);
4553
4554     hres = IHTMLStyle_put_borderLeft(style, sDefault);
4555     ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres);
4556     SysFreeString(sDefault);
4557
4558     /* backgroundPositionX */
4559     hres = IHTMLStyle_get_backgroundPositionX(style, &vDefault);
4560     ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres);
4561
4562     V_VT(&v) = VT_BSTR;
4563     V_BSTR(&v) = a2bstr("10px");
4564     hres = IHTMLStyle_put_backgroundPositionX(style, v);
4565     ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres);
4566     VariantClear(&v);
4567
4568     hres = IHTMLStyle_get_backgroundPositionX(style, &v);
4569     ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres);
4570     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4571     VariantClear(&v);
4572
4573     hres = IHTMLStyle_put_backgroundPositionX(style, vDefault);
4574     ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres);
4575     VariantClear(&vDefault);
4576
4577     /* backgroundPositionY */
4578     hres = IHTMLStyle_get_backgroundPositionY(style, &vDefault);
4579     ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres);
4580
4581     V_VT(&v) = VT_BSTR;
4582     V_BSTR(&v) = a2bstr("10px");
4583     hres = IHTMLStyle_put_backgroundPositionY(style, v);
4584     ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres);
4585     VariantClear(&v);
4586
4587     hres = IHTMLStyle_get_backgroundPositionY(style, &v);
4588     ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres);
4589     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4590     VariantClear(&v);
4591
4592     hres = IHTMLStyle_put_backgroundPositionY(style, vDefault);
4593     ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres);
4594     VariantClear(&vDefault);
4595
4596      /* borderTopWidth */
4597     hres = IHTMLStyle_get_borderTopWidth(style, &vDefault);
4598     ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres);
4599
4600     V_VT(&v) = VT_BSTR;
4601     V_BSTR(&v) = a2bstr("10px");
4602     hres = IHTMLStyle_put_borderTopWidth(style, v);
4603     ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres);
4604     VariantClear(&v);
4605
4606     hres = IHTMLStyle_get_borderTopWidth(style, &v);
4607     ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres);
4608     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4609     VariantClear(&v);
4610
4611     hres = IHTMLStyle_put_borderTopWidth(style, vDefault);
4612     ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres);
4613     VariantClear(&vDefault);
4614
4615     /* borderRightWidth */
4616     hres = IHTMLStyle_get_borderRightWidth(style, &vDefault);
4617     ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres);
4618
4619     V_VT(&v) = VT_BSTR;
4620     V_BSTR(&v) = a2bstr("10");
4621     hres = IHTMLStyle_put_borderRightWidth(style, v);
4622     ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres);
4623     VariantClear(&v);
4624
4625     hres = IHTMLStyle_get_borderRightWidth(style, &v);
4626     ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres);
4627     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4628     VariantClear(&v);
4629
4630     hres = IHTMLStyle_put_borderRightWidth(style, vDefault);
4631     ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres);
4632     VariantClear(&vDefault);
4633
4634     /* borderBottomWidth */
4635     hres = IHTMLStyle_get_borderBottomWidth(style, &vDefault);
4636     ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres);
4637
4638     V_VT(&v) = VT_BSTR;
4639     V_BSTR(&v) = a2bstr("10");
4640     hres = IHTMLStyle_put_borderBottomWidth(style, v);
4641     ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres);
4642     VariantClear(&v);
4643
4644     hres = IHTMLStyle_get_borderBottomWidth(style, &v);
4645     ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres);
4646     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4647     VariantClear(&v);
4648
4649     hres = IHTMLStyle_put_borderBottomWidth(style, vDefault);
4650     ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres);
4651     VariantClear(&vDefault);
4652
4653     /* borderLeftWidth */
4654     hres = IHTMLStyle_get_borderLeftWidth(style, &vDefault);
4655     ok(hres == S_OK, "get_borderLeftWidth: %08x\n", hres);
4656
4657     V_VT(&v) = VT_BSTR;
4658     V_BSTR(&v) = a2bstr("10");
4659     hres = IHTMLStyle_put_borderLeftWidth(style, v);
4660     ok(hres == S_OK, "put_borderLeftWidth: %08x\n", hres);
4661     VariantClear(&v);
4662
4663     hres = IHTMLStyle_get_borderLeftWidth(style, &v);
4664     ok(hres == S_OK, "get_borderLeftWidth: %08x\n", hres);
4665     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4666     VariantClear(&v);
4667
4668     hres = IHTMLStyle_put_borderLeftWidth(style, vDefault);
4669     ok(hres == S_OK, "put_borderLeftWidth: %08x\n", hres);
4670     VariantClear(&vDefault);
4671
4672     /* wordSpacing */
4673     hres = IHTMLStyle_get_wordSpacing(style, &vDefault);
4674     ok(hres == S_OK, "get_wordSpacing: %08x\n", hres);
4675
4676     V_VT(&v) = VT_BSTR;
4677     V_BSTR(&v) = a2bstr("10");
4678     hres = IHTMLStyle_put_wordSpacing(style, v);
4679     ok(hres == S_OK, "put_wordSpacing: %08x\n", hres);
4680     VariantClear(&v);
4681
4682     hres = IHTMLStyle_get_wordSpacing(style, &v);
4683     ok(hres == S_OK, "get_wordSpacing: %08x\n", hres);
4684     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4685     ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4686     VariantClear(&v);
4687
4688     hres = IHTMLStyle_put_wordSpacing(style, vDefault);
4689     ok(hres == S_OK, "put_wordSpacing: %08x\n", hres);
4690     VariantClear(&vDefault);
4691
4692     /* letterSpacing */
4693     hres = IHTMLStyle_get_letterSpacing(style, &vDefault);
4694     ok(hres == S_OK, "get_letterSpacing: %08x\n", hres);
4695
4696     V_VT(&v) = VT_BSTR;
4697     V_BSTR(&v) = a2bstr("11");
4698     hres = IHTMLStyle_put_letterSpacing(style, v);
4699     ok(hres == S_OK, "put_letterSpacing: %08x\n", hres);
4700     VariantClear(&v);
4701
4702     hres = IHTMLStyle_get_letterSpacing(style, &v);
4703     ok(hres == S_OK, "get_letterSpacing: %08x\n", hres);
4704     ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
4705     ok(!strcmp_wa(V_BSTR(&v), "11px"), "expected 10px = %s\n", wine_dbgstr_w(V_BSTR(&v)));
4706     VariantClear(&v);
4707
4708     hres = IHTMLStyle_put_letterSpacing(style, vDefault);
4709     ok(hres == S_OK, "put_letterSpacing: %08x\n", hres);
4710     VariantClear(&vDefault);
4711
4712     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle2, (void**)&style2);
4713     ok(hres == S_OK, "Could not get IHTMLStyle2 iface: %08x\n", hres);
4714     if(SUCCEEDED(hres)) {
4715         test_style2(style2);
4716         IHTMLStyle2_Release(style2);
4717     }
4718
4719     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle3, (void**)&style3);
4720     ok(hres == S_OK, "Could not get IHTMLStyle3 iface: %08x\n", hres);
4721     if(SUCCEEDED(hres)) {
4722         test_style3(style3);
4723         IHTMLStyle3_Release(style3);
4724     }
4725
4726     hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle4, (void**)&style4);
4727     ok(hres == S_OK, "Could not get IHTMLStyle4 iface: %08x\n", hres);
4728     if(SUCCEEDED(hres)) {
4729         test_style4(style4);
4730         IHTMLStyle4_Release(style4);
4731     }
4732 }
4733
4734 static void test_set_csstext(IHTMLStyle *style)
4735 {
4736     VARIANT v;
4737     HRESULT hres;
4738
4739     test_style_set_csstext(style, "background-color: black;");
4740
4741     hres = IHTMLStyle_get_backgroundColor(style, &v);
4742     ok(hres == S_OK, "get_backgroundColor: %08x\n", hres);
4743     ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v));
4744     ok(!strcmp_wa(V_BSTR(&v), "black"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
4745     VariantClear(&v);
4746 }
4747
4748 static void test_default_selection(IHTMLDocument2 *doc)
4749 {
4750     IHTMLSelectionObject *selection;
4751     IHTMLTxtRange *range;
4752     IDispatch *disp;
4753     BSTR str;
4754     HRESULT hres;
4755
4756     hres = IHTMLDocument2_get_selection(doc, &selection);
4757     ok(hres == S_OK, "get_selection failed: %08x\n", hres);
4758
4759     hres = IHTMLSelectionObject_get_type(selection, &str);
4760     ok(hres == S_OK, "get_type failed: %08x\n", hres);
4761     ok(!strcmp_wa(str, "None"), "type = %s\n", wine_dbgstr_w(str));
4762     SysFreeString(str);
4763
4764     hres = IHTMLSelectionObject_createRange(selection, &disp);
4765     IHTMLSelectionObject_Release(selection);
4766     ok(hres == S_OK, "createRange failed: %08x\n", hres);
4767
4768     hres = IDispatch_QueryInterface(disp, &IID_IHTMLTxtRange, (void**)&range);
4769     IDispatch_Release(disp);
4770     ok(hres == S_OK, "Could not get IHTMLTxtRange interface: %08x\n", hres);
4771
4772     test_range_text(range, NULL);
4773     IHTMLTxtRange_Release(range);
4774 }
4775
4776 static void test_doc_elem(IHTMLDocument2 *doc)
4777 {
4778     IHTMLDocument2 *doc_node, *owner_doc;
4779     IHTMLElement *elem;
4780     IHTMLDocument3 *doc3;
4781     HRESULT hres;
4782
4783     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
4784     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres);
4785
4786     hres = IHTMLDocument3_get_documentElement(doc3, &elem);
4787     IHTMLDocument3_Release(doc3);
4788     ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
4789
4790     test_node_name((IUnknown*)elem, "HTML");
4791     test_elem_tag((IUnknown*)elem, "HTML");
4792
4793     doc_node = get_doc_node(doc);
4794     owner_doc = get_owner_doc((IUnknown*)elem);
4795     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
4796     IHTMLDocument2_Release(owner_doc);
4797
4798     owner_doc = get_owner_doc((IUnknown*)doc_node);
4799     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
4800     IHTMLDocument2_Release(doc_node);
4801
4802     test_elem_client_rect((IUnknown*)elem);
4803
4804     IHTMLElement_Release(elem);
4805 }
4806
4807 static void test_default_body(IHTMLBodyElement *body)
4808 {
4809     LONG l;
4810     BSTR bstr;
4811     HRESULT hres;
4812     VARIANT v;
4813
4814     bstr = (void*)0xdeadbeef;
4815     hres = IHTMLBodyElement_get_background(body, &bstr);
4816     ok(hres == S_OK, "get_background failed: %08x\n", hres);
4817     ok(bstr == NULL, "bstr != NULL\n");
4818
4819     l = elem_get_scroll_height((IUnknown*)body);
4820     ok(l != -1, "scrollHeight == -1\n");
4821     l = elem_get_scroll_width((IUnknown*)body);
4822     ok(l != -1, "scrollWidth == -1\n");
4823     l = elem_get_scroll_top((IUnknown*)body);
4824     ok(!l, "scrollTop = %d\n", l);
4825     elem_get_scroll_left((IUnknown*)body);
4826
4827     /* get_text tests */
4828     hres = IHTMLBodyElement_get_text(body, &v);
4829     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4830     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4831     ok(bstr == NULL, "bstr != NULL\n");
4832
4833     /* get_text - Invalid Text */
4834     V_VT(&v) = VT_BSTR;
4835     V_BSTR(&v) = a2bstr("Invalid");
4836     hres = IHTMLBodyElement_put_text(body, v);
4837     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4838     VariantClear(&v);
4839
4840     V_VT(&v) = VT_NULL;
4841     hres = IHTMLBodyElement_get_text(body, &v);
4842     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4843     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4844     ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v = %s, expected '#00a0d0'\n", wine_dbgstr_w(V_BSTR(&v)));
4845     VariantClear(&v);
4846
4847     /* get_text - Valid Text */
4848     V_VT(&v) = VT_BSTR;
4849     V_BSTR(&v) = a2bstr("#FF0000");
4850     hres = IHTMLBodyElement_put_text(body, v);
4851     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4852     VariantClear(&v);
4853
4854     V_VT(&v) = VT_NULL;
4855     hres = IHTMLBodyElement_get_text(body, &v);
4856     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
4857     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
4858     ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v = %s, expected '#ff0000'\n", wine_dbgstr_w(V_BSTR(&v)));
4859     VariantClear(&v);
4860 }
4861
4862 static void test_body_funs(IHTMLBodyElement *body)
4863 {
4864     VARIANT vbg, vDefaultbg;
4865     HRESULT hres;
4866
4867     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
4868     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
4869     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
4870     ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
4871
4872     V_VT(&vbg) = VT_BSTR;
4873     V_BSTR(&vbg) = a2bstr("red");
4874     hres = IHTMLBodyElement_put_bgColor(body, vbg);
4875     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
4876     VariantClear(&vbg);
4877
4878     hres = IHTMLBodyElement_get_bgColor(body, &vbg);
4879     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
4880     ok(V_VT(&vDefaultbg) == VT_BSTR, "V_VT(&vDefaultbg) != VT_BSTR\n");
4881     ok(!strcmp_wa(V_BSTR(&vbg), "#ff0000"), "Unexpected bgcolor %s\n", wine_dbgstr_w(V_BSTR(&vbg)));
4882     VariantClear(&vbg);
4883
4884     /* Restore Originial */
4885     hres = IHTMLBodyElement_put_bgColor(body, vDefaultbg);
4886     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
4887     VariantClear(&vDefaultbg);
4888 }
4889
4890 static void test_window(IHTMLDocument2 *doc)
4891 {
4892     IHTMLWindow2 *window, *window2, *self;
4893     IHTMLDocument2 *doc2 = NULL;
4894     IDispatch *disp;
4895     IUnknown *unk;
4896     BSTR str;
4897     HRESULT hres;
4898
4899     hres = IHTMLDocument2_get_parentWindow(doc, &window);
4900     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
4901     test_ifaces((IUnknown*)window, window_iids);
4902     test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, "[object]");
4903
4904     hres = IHTMLWindow2_get_document(window, &doc2);
4905     ok(hres == S_OK, "get_document failed: %08x\n", hres);
4906     ok(doc2 != NULL, "doc2 == NULL\n");
4907
4908     test_ifaces((IUnknown*)doc2, doc_node_iids);
4909     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
4910
4911     test_ifaces((IUnknown*)doc, doc_obj_iids);
4912     test_disp((IUnknown*)doc2, &DIID_DispHTMLDocument, "[object]");
4913
4914     unk = (void*)0xdeadbeef;
4915     hres = IHTMLDocument2_QueryInterface(doc2, &IID_ICustomDoc, (void**)&unk);
4916     ok(hres == E_NOINTERFACE, "QueryInterface(IID_ICustomDoc) returned: %08x\n", hres);
4917     ok(!unk, "unk = %p\n", unk);
4918
4919     IHTMLDocument_Release(doc2);
4920
4921     hres = IHTMLWindow2_get_window(window, &window2);
4922     ok(hres == S_OK, "get_window failed: %08x\n", hres);
4923     ok(window2 != NULL, "window2 == NULL\n");
4924
4925     hres = IHTMLWindow2_get_self(window, &self);
4926     ok(hres == S_OK, "get_self failed: %08x\n", hres);
4927     ok(window2 != NULL, "self == NULL\n");
4928
4929     ok(self == window2, "self != window2\n");
4930
4931     IHTMLWindow2_Release(window2);
4932     IHTMLWindow2_Release(self);
4933
4934     disp = NULL;
4935     hres = IHTMLDocument2_get_Script(doc, &disp);
4936     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
4937     ok(disp == (void*)window, "disp != window\n");
4938     IDispatch_Release(disp);
4939
4940     hres = IHTMLWindow2_toString(window, NULL);
4941     ok(hres == E_INVALIDARG, "toString failed: %08x\n", hres);
4942
4943     str = NULL;
4944     hres = IHTMLWindow2_toString(window, &str);
4945     ok(hres == S_OK, "toString failed: %08x\n", hres);
4946     ok(!strcmp_wa(str, "[object]"), "toString returned %s\n", wine_dbgstr_w(str));
4947     SysFreeString(str);
4948
4949     test_window_name(window, NULL);
4950     set_window_name(window, "test");
4951     test_window_length(window, 0);
4952     test_screen(window);
4953
4954     IHTMLWindow2_Release(window);
4955 }
4956
4957 static void test_defaults(IHTMLDocument2 *doc)
4958 {
4959     IHTMLStyleSheetsCollection *stylesheetcol;
4960     IHTMLCurrentStyle *cstyle;
4961     IHTMLBodyElement *body;
4962     IHTMLElement2 *elem2;
4963     IHTMLElement *elem;
4964     IHTMLStyle *style;
4965     LONG l;
4966     HRESULT hres;
4967     IHTMLElementCollection *collection;
4968
4969     hres = IHTMLDocument2_get_body(doc, &elem);
4970     ok(hres == S_OK, "get_body failed: %08x\n", hres);
4971
4972     hres = IHTMLDocument2_get_images(doc, NULL);
4973     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4974
4975     hres = IHTMLDocument2_get_images(doc, &collection);
4976     ok(hres == S_OK, "get_images failed: %08x\n", hres);
4977     if(hres == S_OK)
4978     {
4979         test_elem_collection((IUnknown*)collection, NULL, 0);
4980         IHTMLElementCollection_Release(collection);
4981     }
4982
4983     hres = IHTMLDocument2_get_applets(doc, NULL);
4984     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4985
4986     hres = IHTMLDocument2_get_applets(doc, &collection);
4987     ok(hres == S_OK, "get_applets failed: %08x\n", hres);
4988     if(hres == S_OK)
4989     {
4990         test_elem_collection((IUnknown*)collection, NULL, 0);
4991         IHTMLElementCollection_Release(collection);
4992     }
4993
4994     hres = IHTMLDocument2_get_links(doc, NULL);
4995     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
4996
4997     hres = IHTMLDocument2_get_links(doc, &collection);
4998     ok(hres == S_OK, "get_links failed: %08x\n", hres);
4999     if(hres == S_OK)
5000     {
5001         test_elem_collection((IUnknown*)collection, NULL, 0);
5002         IHTMLElementCollection_Release(collection);
5003     }
5004
5005     hres = IHTMLDocument2_get_forms(doc, NULL);
5006     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5007
5008     hres = IHTMLDocument2_get_forms(doc, &collection);
5009     ok(hres == S_OK, "get_forms failed: %08x\n", hres);
5010     if(hres == S_OK)
5011     {
5012         test_elem_collection((IUnknown*)collection, NULL, 0);
5013         IHTMLElementCollection_Release(collection);
5014     }
5015
5016     hres = IHTMLDocument2_get_anchors(doc, NULL);
5017     ok(hres == E_INVALIDARG, "hres %08x\n", hres);
5018
5019     hres = IHTMLDocument2_get_anchors(doc, &collection);
5020     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
5021     if(hres == S_OK)
5022     {
5023         test_elem_collection((IUnknown*)collection, NULL, 0);
5024         IHTMLElementCollection_Release(collection);
5025     }
5026
5027     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLBodyElement, (void**)&body);
5028     ok(hres == S_OK, "Could not get IHTMBodyElement: %08x\n", hres);
5029     test_default_body(body);
5030     test_body_funs(body);
5031     IHTMLBodyElement_Release(body);
5032
5033     hres = IHTMLElement_get_style(elem, &style);
5034     ok(hres == S_OK, "get_style failed: %08x\n", hres);
5035
5036     test_default_style(style);
5037     test_window(doc);
5038     test_compatmode(doc);
5039     test_location(doc);
5040     test_navigator(doc);
5041
5042     elem2 = get_elem2_iface((IUnknown*)elem);
5043     hres = IHTMLElement2_get_currentStyle(elem2, &cstyle);
5044     ok(hres == S_OK, "get_currentStyle failed: %08x\n", hres);
5045     if(SUCCEEDED(hres)) {
5046         test_current_style(cstyle);
5047         IHTMLCurrentStyle_Release(cstyle);
5048     }
5049     IHTMLElement2_Release(elem2);
5050
5051     IHTMLElement_Release(elem);
5052
5053     test_set_csstext(style);
5054     IHTMLStyle_Release(style);
5055
5056     hres = IHTMLDocument2_get_styleSheets(doc, &stylesheetcol);
5057     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
5058
5059     l = 0xdeadbeef;
5060     hres = IHTMLStyleSheetsCollection_get_length(stylesheetcol, &l);
5061     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5062     ok(l == 0, "length = %d\n", l);
5063
5064     IHTMLStyleSheetsCollection_Release(stylesheetcol);
5065
5066     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFiltersCollection, (void**)&body);
5067     ok(hres == E_NOINTERFACE, "got interface IHTMLFiltersCollection\n");
5068
5069     test_default_selection(doc);
5070     test_doc_title(doc, "");
5071 }
5072
5073 static void test_tr_elem(IHTMLElement *elem)
5074 {
5075     IHTMLElementCollection *col;
5076     IHTMLTableRow *row;
5077     HRESULT hres;
5078
5079     static const elem_type_t cell_types[] = {ET_TD,ET_TD};
5080
5081     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTableRow, (void**)&row);
5082     ok(hres == S_OK, "Could not get IHTMLTableRow iface: %08x\n", hres);
5083     if(FAILED(hres))
5084         return;
5085
5086     col = NULL;
5087     hres = IHTMLTableRow_get_cells(row, &col);
5088     ok(hres == S_OK, "get_cells failed: %08x\n", hres);
5089     ok(col != NULL, "get_cells returned NULL\n");
5090
5091     test_elem_collection((IUnknown*)col, cell_types, sizeof(cell_types)/sizeof(*cell_types));
5092     IHTMLElementCollection_Release(col);
5093
5094     IHTMLTable_Release(row);
5095 }
5096
5097 static void test_table_elem(IHTMLElement *elem)
5098 {
5099     IHTMLElementCollection *col;
5100     IHTMLTable *table;
5101     IHTMLDOMNode *node;
5102     HRESULT hres;
5103
5104     static const elem_type_t row_types[] = {ET_TR,ET_TR};
5105     static const elem_type_t all_types[] = {ET_TBODY,ET_TR,ET_TR,ET_TD,ET_TD};
5106
5107     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLTable, (void**)&table);
5108     ok(hres == S_OK, "Could not get IHTMLTable iface: %08x\n", hres);
5109     if(FAILED(hres))
5110         return;
5111
5112     col = NULL;
5113     hres = IHTMLTable_get_rows(table, &col);
5114     ok(hres == S_OK, "get_rows failed: %08x\n", hres);
5115     ok(col != NULL, "get_ros returned NULL\n");
5116
5117     test_elem_collection((IUnknown*)col, row_types, sizeof(row_types)/sizeof(*row_types));
5118     IHTMLElementCollection_Release(col);
5119
5120     test_elem_all((IUnknown*)table, all_types, sizeof(all_types)/sizeof(*all_types));
5121
5122     node = clone_node((IUnknown*)table, VARIANT_TRUE);
5123     test_elem_tag((IUnknown*)node, "TABLE");
5124     test_elem_all((IUnknown*)node, all_types, sizeof(all_types)/sizeof(*all_types));
5125     IHTMLDOMNode_Release(node);
5126
5127     node = clone_node((IUnknown*)table, VARIANT_FALSE);
5128     test_elem_tag((IUnknown*)node, "TABLE");
5129     test_elem_all((IUnknown*)node, NULL, 0);
5130     IHTMLDOMNode_Release(node);
5131
5132     IHTMLTable_Release(table);
5133 }
5134
5135 static void doc_write(IHTMLDocument2 *doc, BOOL ln, const char *text)
5136 {
5137     SAFEARRAYBOUND dim;
5138     SAFEARRAY *sa;
5139     VARIANT *var;
5140     BSTR str;
5141     HRESULT hres;
5142
5143     dim.lLbound = 0;
5144     dim.cElements = 1;
5145     sa = SafeArrayCreate(VT_VARIANT, 1, &dim);
5146     SafeArrayAccessData(sa, (void**)&var);
5147     V_VT(var) = VT_BSTR;
5148     V_BSTR(var) = str = a2bstr(text);
5149     SafeArrayUnaccessData(sa);
5150
5151     if(ln)
5152         hres = IHTMLDocument2_writeln(doc, sa);
5153     else
5154         hres = IHTMLDocument2_write(doc, sa);
5155     ok(hres == S_OK, "write failed: %08x\n", hres);
5156
5157     SysFreeString(str);
5158     SafeArrayDestroy(sa);
5159 }
5160
5161 static void test_frame_doc(IUnknown *frame_elem, BOOL iframe)
5162 {
5163     IHTMLDocument2 *window_doc, *elem_doc;
5164     IHTMLFrameElement3 *frame_elem3;
5165     IHTMLWindow2 *content_window;
5166     HRESULT hres;
5167
5168     content_window = get_frame_content_window(frame_elem);
5169     window_doc = get_window_doc(content_window);
5170     IHTMLWindow2_Release(content_window);
5171
5172     elem_doc = get_elem_doc(frame_elem);
5173     ok(iface_cmp((IUnknown*)window_doc, (IUnknown*)elem_doc), "content_doc != elem_doc\n");
5174
5175     if(!iframe) {
5176         hres = IUnknown_QueryInterface(frame_elem, &IID_IHTMLFrameElement3, (void**)&frame_elem3);
5177         if(SUCCEEDED(hres)) {
5178             IDispatch *disp = NULL;
5179
5180             hres = IHTMLFrameElement3_get_contentDocument(frame_elem3, &disp);
5181             ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres);
5182             ok(disp != NULL, "contentDocument == NULL\n");
5183             ok(iface_cmp((IUnknown*)disp, (IUnknown*)window_doc), "contentDocument != contentWindow.document\n");
5184
5185             IDispatch_Release(disp);
5186             IHTMLFrameElement3_Release(frame_elem3);
5187         }else {
5188             win_skip("IHTMLFrameElement3 not supported\n");
5189         }
5190     }
5191
5192     IHTMLDocument2_Release(elem_doc);
5193     IHTMLDocument2_Release(window_doc);
5194 }
5195
5196 static void test_iframe_elem(IHTMLElement *elem)
5197 {
5198     IHTMLDocument2 *content_doc, *owner_doc;
5199     IHTMLElementCollection *col;
5200     IHTMLWindow2 *content_window;
5201     IDispatch *disp;
5202     VARIANT errv;
5203     BSTR str;
5204     HRESULT hres;
5205
5206     static const elem_type_t all_types[] = {
5207         ET_HTML,
5208         ET_HEAD,
5209         ET_TITLE,
5210         ET_BODY,
5211         ET_BR
5212     };
5213
5214     test_frame_doc((IUnknown*)elem, TRUE);
5215
5216     content_window = get_frame_content_window((IUnknown*)elem);
5217     test_window_length(content_window, 0);
5218
5219     content_doc = get_window_doc(content_window);
5220     IHTMLWindow2_Release(content_window);
5221
5222     str = a2bstr("text/html");
5223     V_VT(&errv) = VT_ERROR;
5224     disp = NULL;
5225     hres = IHTMLDocument2_open(content_doc, str, errv, errv, errv, &disp);
5226     SysFreeString(str);
5227     ok(hres == S_OK, "open failed: %08x\n", hres);
5228     ok(disp != NULL, "disp == NULL\n");
5229     ok(iface_cmp((IUnknown*)disp, (IUnknown*)content_window), "disp != content_window\n");
5230     IDispatch_Release(disp);
5231
5232     doc_write(content_doc, FALSE, "<html><head><title>test</title></head><body><br /></body>");
5233     doc_write(content_doc, TRUE, "</html>");
5234
5235     hres = IHTMLDocument2_get_all(content_doc, &col);
5236     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5237     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5238     IHTMLElementCollection_Release(col);
5239
5240     hres = IHTMLDocument2_close(content_doc);
5241     ok(hres == S_OK, "close failed: %08x\n", hres);
5242
5243     owner_doc = get_owner_doc((IUnknown*)content_doc);
5244     ok(!owner_doc, "owner_doc = %p\n", owner_doc);
5245
5246     IHTMLDocument2_Release(content_doc);
5247 }
5248
5249 static void test_stylesheet(IDispatch *disp)
5250 {
5251     IHTMLStyleSheetRulesCollection *col = NULL;
5252     IHTMLStyleSheet *stylesheet;
5253     HRESULT hres;
5254
5255     hres = IDispatch_QueryInterface(disp, &IID_IHTMLStyleSheet, (void**)&stylesheet);
5256     ok(hres == S_OK, "Could not get IHTMLStyleSheet: %08x\n", hres);
5257
5258     hres = IHTMLStyleSheet_get_rules(stylesheet, &col);
5259     ok(hres == S_OK, "get_rules failed: %08x\n", hres);
5260     ok(col != NULL, "col == NULL\n");
5261
5262     IHTMLStyleSheetRulesCollection_Release(col);
5263     IHTMLStyleSheet_Release(stylesheet);
5264 }
5265
5266 static void test_stylesheets(IHTMLDocument2 *doc)
5267 {
5268     IHTMLStyleSheetsCollection *col = NULL;
5269     VARIANT idx, res;
5270     LONG len = 0;
5271     HRESULT hres;
5272
5273     hres = IHTMLDocument2_get_styleSheets(doc, &col);
5274     ok(hres == S_OK, "get_styleSheets failed: %08x\n", hres);
5275     ok(col != NULL, "col == NULL\n");
5276
5277     hres = IHTMLStyleSheetsCollection_get_length(col, &len);
5278     ok(hres == S_OK, "get_length failed: %08x\n", hres);
5279     ok(len == 1, "len=%d\n", len);
5280
5281     VariantInit(&res);
5282     V_VT(&idx) = VT_I4;
5283     V_I4(&idx) = 0;
5284
5285     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5286     ok(hres == S_OK, "item failed: %08x\n", hres);
5287     ok(V_VT(&res) == VT_DISPATCH, "V_VT(res) = %d\n", V_VT(&res));
5288     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5289     test_stylesheet(V_DISPATCH(&res));
5290     VariantClear(&res);
5291
5292     V_VT(&res) = VT_I4;
5293     V_VT(&idx) = VT_I4;
5294     V_I4(&idx) = 1;
5295
5296     hres = IHTMLStyleSheetsCollection_item(col, &idx, &res);
5297     ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5298     ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
5299     ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
5300     VariantClear(&res);
5301
5302     IHTMLStyleSheetsCollection_Release(col);
5303 }
5304
5305 static void test_child_col_disp(IHTMLDOMChildrenCollection *col)
5306 {
5307     IDispatchEx *dispex;
5308     IHTMLDOMNode *node;
5309     DISPPARAMS dp = {NULL, NULL, 0, 0};
5310     VARIANT var;
5311     EXCEPINFO ei;
5312     LONG type;
5313     DISPID id;
5314     BSTR bstr;
5315     HRESULT hres;
5316
5317     static const WCHAR w0[] = {'0',0};
5318     static const WCHAR w100[] = {'1','0','0',0};
5319
5320     hres = IHTMLDOMChildrenCollection_QueryInterface(col, &IID_IDispatchEx, (void**)&dispex);
5321     ok(hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
5322
5323     bstr = SysAllocString(w0);
5324     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5325     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
5326     SysFreeString(bstr);
5327
5328     VariantInit(&var);
5329     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
5330     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
5331     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
5332     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
5333     node = get_node_iface((IUnknown*)V_DISPATCH(&var));
5334     type = get_node_type((IUnknown*)node);
5335     ok(type == 3, "type=%d\n", type);
5336     IHTMLDOMNode_Release(node);
5337     VariantClear(&var);
5338
5339     bstr = SysAllocString(w100);
5340     hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
5341     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
5342     SysFreeString(bstr);
5343
5344     IDispatchEx_Release(dispex);
5345 }
5346
5347
5348
5349 static void test_elems(IHTMLDocument2 *doc)
5350 {
5351     IHTMLElementCollection *col;
5352     IHTMLDOMChildrenCollection *child_col;
5353     IHTMLElement *elem, *elem2, *elem3;
5354     IHTMLDOMNode *node, *node2;
5355     IHTMLWindow2 *window;
5356     IDispatch *disp;
5357     LONG type;
5358     HRESULT hres;
5359     IHTMLElementCollection *collection;
5360     IHTMLDocument3 *doc3;
5361     BSTR str;
5362
5363     static const elem_type_t all_types[] = {
5364         ET_HTML,
5365         ET_HEAD,
5366         ET_TITLE,
5367         ET_STYLE,
5368         ET_BODY,
5369         ET_COMMENT,
5370         ET_A,
5371         ET_INPUT,
5372         ET_SELECT,
5373         ET_OPTION,
5374         ET_OPTION,
5375         ET_TEXTAREA,
5376         ET_TABLE,
5377         ET_TBODY,
5378         ET_TR,
5379         ET_TR,
5380         ET_TD,
5381         ET_TD,
5382         ET_SCRIPT,
5383         ET_TEST,
5384         ET_IMG,
5385         ET_IFRAME,
5386         ET_FORM
5387     };
5388
5389     static const elem_type_t item_types[] = {
5390         ET_A,
5391         ET_OPTION,
5392         ET_TEXTAREA
5393     };
5394
5395     hres = IHTMLDocument2_get_all(doc, &col);
5396     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5397     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5398     test_elem_col_item(col, "x", item_types, sizeof(item_types)/sizeof(item_types[0]));
5399     IHTMLElementCollection_Release(col);
5400
5401     hres = IHTMLDocument2_get_images(doc, &collection);
5402     ok(hres == S_OK, "get_images failed: %08x\n", hres);
5403     if(hres == S_OK)
5404     {
5405         static const elem_type_t images_types[] = {ET_IMG};
5406         test_elem_collection((IUnknown*)collection, images_types, 1);
5407
5408         IHTMLElementCollection_Release(collection);
5409     }
5410
5411     hres = IHTMLDocument2_get_links(doc, &collection);
5412     ok(hres == S_OK, "get_links failed: %08x\n", hres);
5413     if(hres == S_OK)
5414     {
5415         static const elem_type_t images_types[] = {ET_A};
5416         test_elem_collection((IUnknown*)collection, images_types, 1);
5417
5418         IHTMLElementCollection_Release(collection);
5419     }
5420
5421     hres = IHTMLDocument2_get_anchors(doc, &collection);
5422     ok(hres == S_OK, "get_anchors failed: %08x\n", hres);
5423     if(hres == S_OK)
5424     {
5425         static const elem_type_t anchor_types[] = {ET_A};
5426         test_elem_collection((IUnknown*)collection, anchor_types, 1);
5427
5428         IHTMLElementCollection_Release(collection);
5429     }
5430
5431     elem = get_doc_elem(doc);
5432     test_elem_all((IUnknown*)elem, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1);
5433     IHTMLElement_Release(elem);
5434
5435     get_elem_by_id(doc, "xxx", FALSE);
5436     elem = get_doc_elem_by_id(doc, "xxx");
5437     ok(!elem, "elem != NULL\n");
5438
5439     elem = get_doc_elem_by_id(doc, "s");
5440     ok(elem != NULL, "elem == NULL\n");
5441     if(elem) {
5442         test_elem_type((IUnknown*)elem, ET_SELECT);
5443         test_elem_attr(elem, "xxx", NULL);
5444         test_elem_attr(elem, "id", "s");
5445         test_elem_class((IUnknown*)elem, NULL);
5446         test_elem_set_class((IUnknown*)elem, "cl");
5447         test_elem_set_class((IUnknown*)elem, NULL);
5448         test_elem_tabindex((IUnknown*)elem, 0);
5449         test_elem_set_tabindex((IUnknown*)elem, 1);
5450         test_elem_filters((IUnknown*)elem);
5451
5452         node = test_node_get_parent((IUnknown*)elem);
5453         ok(node != NULL, "node == NULL\n");
5454         test_node_name((IUnknown*)node, "BODY");
5455         node2 = test_node_get_parent((IUnknown*)node);
5456         IHTMLDOMNode_Release(node);
5457         ok(node2 != NULL, "node == NULL\n");
5458         test_node_name((IUnknown*)node2, "HTML");
5459         node = test_node_get_parent((IUnknown*)node2);
5460         IHTMLDOMNode_Release(node2);
5461         ok(node != NULL, "node == NULL\n");
5462         if (node)
5463         {
5464             test_node_name((IUnknown*)node, "#document");
5465             type = get_node_type((IUnknown*)node);
5466             ok(type == 9, "type=%d, expected 9\n", type);
5467             node2 = test_node_get_parent((IUnknown*)node);
5468             IHTMLDOMNode_Release(node);
5469             ok(node2 == NULL, "node != NULL\n");
5470         }
5471
5472         elem2 = test_elem_get_parent((IUnknown*)elem);
5473         ok(elem2 != NULL, "elem2 == NULL\n");
5474         test_node_name((IUnknown*)elem2, "BODY");
5475         elem3 = test_elem_get_parent((IUnknown*)elem2);
5476         IHTMLElement_Release(elem2);
5477         ok(elem3 != NULL, "elem3 == NULL\n");
5478         test_node_name((IUnknown*)elem3, "HTML");
5479         elem2 = test_elem_get_parent((IUnknown*)elem3);
5480         IHTMLElement_Release(elem3);
5481         ok(elem2 == NULL, "elem2 != NULL\n");
5482
5483         test_elem_getelembytag((IUnknown*)elem, ET_OPTION, 2);
5484         test_elem_getelembytag((IUnknown*)elem, ET_SELECT, 0);
5485         test_elem_getelembytag((IUnknown*)elem, ET_HTML, 0);
5486
5487         test_elem_innertext(elem, "opt1opt2");
5488
5489         IHTMLElement_Release(elem);
5490     }
5491
5492     elem = get_elem_by_id(doc, "s", TRUE);
5493     if(elem) {
5494         IHTMLSelectElement *select;
5495         IHTMLDocument2 *doc_node, *elem_doc;
5496
5497         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLSelectElement, (void**)&select);
5498         ok(hres == S_OK, "Could not get IHTMLSelectElement interface: %08x\n", hres);
5499
5500         test_select_elem(select);
5501
5502         test_elem_title((IUnknown*)select, NULL);
5503         test_elem_set_title((IUnknown*)select, "Title");
5504         test_elem_title((IUnknown*)select, "Title");
5505         test_elem_offset((IUnknown*)select);
5506
5507         node = get_first_child((IUnknown*)select);
5508         ok(node != NULL, "node == NULL\n");
5509         if(node) {
5510             test_elem_type((IUnknown*)node, ET_OPTION);
5511             IHTMLDOMNode_Release(node);
5512         }
5513
5514         type = get_node_type((IUnknown*)select);
5515         ok(type == 1, "type=%d\n", type);
5516
5517         IHTMLSelectElement_Release(select);
5518
5519         elem_doc = get_elem_doc((IUnknown*)elem);
5520
5521         doc_node = get_doc_node(doc);
5522         ok(iface_cmp((IUnknown*)elem_doc, (IUnknown*)doc_node), "disp != doc\n");
5523         IHTMLDocument2_Release(doc_node);
5524         IHTMLDocument2_Release(elem_doc);
5525
5526         IHTMLElement_Release(elem);
5527     }
5528
5529     elem = get_elem_by_id(doc, "sc", TRUE);
5530     if(elem) {
5531         IHTMLScriptElement *script;
5532         BSTR type;
5533
5534         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLScriptElement, (void**)&script);
5535         ok(hres == S_OK, "Could not get IHTMLScriptElement interface: %08x\n", hres);
5536
5537         if(hres == S_OK)
5538         {
5539             VARIANT_BOOL vb;
5540
5541             hres = IHTMLScriptElement_get_type(script, &type);
5542             ok(hres == S_OK, "get_type failed: %08x\n", hres);
5543             ok(!strcmp_wa(type, "text/javascript"), "Unexpected type %s\n", wine_dbgstr_w(type));
5544             SysFreeString(type);
5545
5546             /* test defer */
5547             hres = IHTMLScriptElement_put_defer(script, VARIANT_TRUE);
5548             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5549
5550             hres = IHTMLScriptElement_get_defer(script, &vb);
5551             ok(hres == S_OK, "get_defer failed: %08x\n", hres);
5552             ok(vb == VARIANT_TRUE, "get_defer result is %08x\n", hres);
5553
5554             hres = IHTMLScriptElement_put_defer(script, VARIANT_FALSE);
5555             ok(hres == S_OK, "put_defer failed: %08x\n", hres);
5556         }
5557
5558         IHTMLScriptElement_Release(script);
5559     }
5560
5561     elem = get_elem_by_id(doc, "in", TRUE);
5562     if(elem) {
5563         IHTMLInputElement *input;
5564
5565         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLInputElement, (void**)&input);
5566         ok(hres == S_OK, "Could not get IHTMLInputElement: %08x\n", hres);
5567
5568         test_elem_id((IUnknown*)elem, "in");
5569         test_elem_put_id((IUnknown*)elem, "newin");
5570         test_input_get_disabled(input, VARIANT_FALSE);
5571         test_input_set_disabled(input, VARIANT_TRUE);
5572         test_input_set_disabled(input, VARIANT_FALSE);
5573         test_elem3_set_disabled((IUnknown*)input, VARIANT_TRUE);
5574         test_input_get_disabled(input, VARIANT_TRUE);
5575         test_elem3_set_disabled((IUnknown*)input, VARIANT_FALSE);
5576         test_input_get_disabled(input, VARIANT_FALSE);
5577         test_elem_client_size((IUnknown*)elem);
5578
5579         test_node_get_value_str((IUnknown*)elem, NULL);
5580         test_node_put_value_str((IUnknown*)elem, "test");
5581         test_node_get_value_str((IUnknown*)elem, NULL);
5582         test_input_value((IUnknown*)elem, NULL);
5583         test_input_put_value((IUnknown*)elem, "test");
5584         test_input_value((IUnknown*)elem, NULL);
5585         test_elem_class((IUnknown*)elem, "testclass");
5586         test_elem_tabindex((IUnknown*)elem, 2);
5587         test_elem_set_tabindex((IUnknown*)elem, 3);
5588         test_elem_title((IUnknown*)elem, "test title");
5589
5590         test_input_get_defaultchecked(input, VARIANT_FALSE);
5591         test_input_set_defaultchecked(input, VARIANT_TRUE);
5592         test_input_set_defaultchecked(input, VARIANT_FALSE);
5593
5594         test_input_get_checked(input, VARIANT_FALSE);
5595         test_input_set_checked(input, VARIANT_TRUE);
5596         test_input_set_checked(input, VARIANT_FALSE);
5597
5598         test_input_src(input, NULL);
5599         test_input_set_src(input, "about:blank");
5600
5601         IHTMLInputElement_Release(input);
5602         IHTMLElement_Release(elem);
5603     }
5604
5605     elem = get_elem_by_id(doc, "imgid", TRUE);
5606     if(elem) {
5607         test_img_src((IUnknown*)elem, "");
5608         test_img_set_src((IUnknown*)elem, "about:blank");
5609         test_img_alt((IUnknown*)elem, NULL);
5610         test_img_set_alt((IUnknown*)elem, "alt test");
5611         test_img_name((IUnknown*)elem, "WineImg");
5612         IHTMLElement_Release(elem);
5613     }
5614
5615     elem = get_doc_elem_by_id(doc, "tbl");
5616     ok(elem != NULL, "elem == NULL\n");
5617     if(elem) {
5618         test_table_elem(elem);
5619         IHTMLElement_Release(elem);
5620     }
5621
5622     elem = get_doc_elem_by_id(doc, "row2");
5623     ok(elem != NULL, "elem == NULL\n");
5624     if(elem) {
5625         test_tr_elem(elem);
5626         IHTMLElement_Release(elem);
5627     }
5628
5629     elem = get_doc_elem_by_id(doc, "ifr");
5630     ok(elem != NULL, "elem == NULL\n");
5631     if(elem) {
5632         test_iframe_elem(elem);
5633         IHTMLElement_Release(elem);
5634     }
5635
5636     elem = get_elem_by_id(doc, "a", TRUE);
5637     if(elem) {
5638         test_anchor_href((IUnknown*)elem, "http://test/");
5639         IHTMLElement_Release(elem);
5640     }
5641
5642     hres = IHTMLDocument2_get_body(doc, &elem);
5643     ok(hres == S_OK, "get_body failed: %08x\n", hres);
5644
5645     node = get_first_child((IUnknown*)elem);
5646     ok(node != NULL, "node == NULL\n");
5647     if(node) {
5648         test_ifaces((IUnknown*)node, text_iids);
5649         test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
5650
5651         node2 = get_first_child((IUnknown*)node);
5652         ok(!node2, "node2 != NULL\n");
5653
5654         type = get_node_type((IUnknown*)node);
5655         ok(type == 3, "type=%d\n", type);
5656
5657         test_node_get_value_str((IUnknown*)node, "text test");
5658         test_node_put_value_str((IUnknown*)elem, "test text");
5659         test_node_get_value_str((IUnknown*)node, "text test");
5660
5661         IHTMLDOMNode_Release(node);
5662     }
5663
5664     child_col = get_child_nodes((IUnknown*)elem);
5665     ok(child_col != NULL, "child_coll == NULL\n");
5666     if(child_col) {
5667         LONG length = 0;
5668
5669         test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection, "[object]");
5670
5671         hres = IHTMLDOMChildrenCollection_get_length(child_col, &length);
5672         ok(hres == S_OK, "get_length failed: %08x\n", hres);
5673         ok(length, "length=0\n");
5674
5675         node2 = NULL;
5676         node = get_child_item(child_col, 0);
5677         ok(node != NULL, "node == NULL\n");
5678         if(node) {
5679             type = get_node_type((IUnknown*)node);
5680             ok(type == 3, "type=%d\n", type);
5681             node2 = node_get_next((IUnknown*)node);
5682             IHTMLDOMNode_Release(node);
5683         }
5684
5685         node = get_child_item(child_col, 1);
5686         ok(node != NULL, "node == NULL\n");
5687         if(node) {
5688             type = get_node_type((IUnknown*)node);
5689             ok(type == 8, "type=%d\n", type);
5690
5691             test_elem_id((IUnknown*)node, NULL);
5692             ok(iface_cmp((IUnknown*)node2, (IUnknown*)node), "node2 != node\n");
5693             IHTMLDOMNode_Release(node2);
5694             IHTMLDOMNode_Release(node);
5695         }
5696
5697         hres = IHTMLDOMChildrenCollection_item(child_col, length - 1, NULL);
5698         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
5699
5700         hres = IHTMLDOMChildrenCollection_item(child_col, length, NULL);
5701         ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres);
5702
5703         hres = IHTMLDOMChildrenCollection_item(child_col, 6000, &disp);
5704         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5705
5706         hres = IHTMLDOMChildrenCollection_item(child_col, length, &disp);
5707         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
5708
5709         test_child_col_disp(child_col);
5710
5711         IHTMLDOMChildrenCollection_Release(child_col);
5712     }
5713
5714     test_elem3_get_disabled((IUnknown*)elem, VARIANT_FALSE);
5715     test_elem3_set_disabled((IUnknown*)elem, VARIANT_TRUE);
5716     test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
5717
5718     IHTMLElement_Release(elem);
5719
5720     test_stylesheets(doc);
5721     test_create_option_elem(doc);
5722     test_create_img_elem(doc);
5723
5724     elem = get_doc_elem_by_id(doc, "tbl");
5725     ok(elem != NULL, "elem = NULL\n");
5726     test_elem_set_innertext(elem, "inner text");
5727     IHTMLElement_Release(elem);
5728
5729     test_doc_title(doc, "test");
5730     test_doc_set_title(doc, "test title");
5731     test_doc_title(doc, "test title");
5732
5733     disp = NULL;
5734     hres = IHTMLDocument2_get_Script(doc, &disp);
5735     ok(hres == S_OK, "get_Script failed: %08x\n", hres);
5736     if(hres == S_OK)
5737     {
5738         IDispatchEx *dispex;
5739         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
5740         ok(hres == S_OK, "IDispatch_QueryInterface failed: %08x\n", hres);
5741         if(hres == S_OK)
5742         {
5743             DISPID pid = -1;
5744             BSTR str = a2bstr("Testing");
5745             hres = IDispatchEx_GetDispID(dispex, str, 1, &pid);
5746             ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
5747             ok(pid != -1, "pid == -1\n");
5748             SysFreeString(str);
5749             IDispatchEx_Release(dispex);
5750         }
5751     }
5752     IDispatch_Release(disp);
5753
5754     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
5755     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
5756
5757     str = a2bstr("img");
5758     hres = IHTMLDocument3_getElementsByTagName(doc3, str, &col);
5759     ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", wine_dbgstr_w(str), hres);
5760     SysFreeString(str);
5761     if(hres == S_OK)
5762     {
5763         static const elem_type_t img_types[] = { ET_IMG };
5764
5765         test_elem_collection((IUnknown*)col, img_types, sizeof(img_types)/sizeof(img_types[0]));
5766         IHTMLElementCollection_Release(col);
5767     }
5768
5769     elem = get_doc_elem_by_id(doc, "y");
5770     test_elem_set_innerhtml((IUnknown*)elem, "inner html");
5771     test_elem_innerhtml((IUnknown*)elem, "inner html");
5772     test_elem_set_innerhtml((IUnknown*)elem, "");
5773     test_elem_innerhtml((IUnknown*)elem, NULL);
5774     node = node_get_next((IUnknown*)elem);
5775     ok(!node, "node = %p\n", node);
5776
5777     elem2 = get_doc_elem_by_id(doc, "x");
5778     test_elem_tag((IUnknown*)elem2, "A");
5779     node = node_get_next((IUnknown*)elem2);
5780     IHTMLDOMNode_Release(node);
5781     IHTMLElement_Release(elem2);
5782     IHTMLElement_Release(elem);
5783
5784     IHTMLDocument3_Release(doc3);
5785
5786     window = get_doc_window(doc);
5787     test_window_name(window, NULL);
5788     set_window_name(window, "test name");
5789     test_window_length(window, 1);
5790     IHTMLWindow2_Release(window);
5791 }
5792
5793 static void test_elems2(IHTMLDocument2 *doc)
5794 {
5795     IHTMLElement *elem, *elem2;
5796
5797     static const elem_type_t outer_types[] = {
5798         ET_BR,
5799         ET_A
5800     };
5801
5802     elem = get_doc_elem_by_id(doc, "divid");
5803
5804     test_elem_set_innerhtml((IUnknown*)elem, "<div id=\"innerid\"></div>");
5805     elem2 = get_doc_elem_by_id(doc, "innerid");
5806     ok(elem2 != NULL, "elem2 == NULL\n");
5807     test_elem_set_outerhtml((IUnknown*)elem2, "<br><a href=\"about:blank\" id=\"aid\">a</a>");
5808     test_elem_all((IUnknown*)elem, outer_types, sizeof(outer_types)/sizeof(*outer_types));
5809     IHTMLElement_Release(elem2);
5810
5811     elem2 = get_doc_elem_by_id(doc, "aid");
5812     ok(elem2 != NULL, "elem2 == NULL\n");
5813     test_elem_set_outerhtml((IUnknown*)elem2, "");
5814     test_elem_all((IUnknown*)elem, outer_types, 1);
5815     IHTMLElement_Release(elem2);
5816
5817     IHTMLElement_Release(elem);
5818 }
5819
5820 static void test_create_elems(IHTMLDocument2 *doc)
5821 {
5822     IHTMLElement *elem, *body, *elem2;
5823     IHTMLDOMNode *node, *node2, *node3, *comment;
5824     IHTMLDocument5 *doc5;
5825     IDispatch *disp;
5826     VARIANT var;
5827     LONG type;
5828     HRESULT hres;
5829     BSTR str;
5830
5831     static const elem_type_t types1[] = { ET_TESTG };
5832
5833     elem = test_create_elem(doc, "TEST");
5834     test_elem_tag((IUnknown*)elem, "TEST");
5835     type = get_node_type((IUnknown*)elem);
5836     ok(type == 1, "type=%d\n", type);
5837     test_ifaces((IUnknown*)elem, elem_iids);
5838     test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]");
5839
5840     hres = IHTMLDocument2_get_body(doc, &body);
5841     ok(hres == S_OK, "get_body failed: %08x\n", hres);
5842     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
5843
5844     node = test_node_append_child((IUnknown*)body, (IUnknown*)elem);
5845     test_node_has_child((IUnknown*)body, VARIANT_TRUE);
5846     elem2 = get_elem_iface((IUnknown*)node);
5847     IHTMLElement_Release(elem2);
5848
5849     hres = IHTMLElement_get_all(body, &disp);
5850     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5851     test_elem_collection((IUnknown*)disp, types1, sizeof(types1)/sizeof(types1[0]));
5852     IDispatch_Release(disp);
5853
5854     test_node_remove_child((IUnknown*)body, node);
5855
5856     hres = IHTMLElement_get_all(body, &disp);
5857     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5858     test_elem_collection((IUnknown*)disp, NULL, 0);
5859     IDispatch_Release(disp);
5860     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
5861
5862     IHTMLElement_Release(elem);
5863     IHTMLDOMNode_Release(node);
5864
5865     node = test_create_text(doc, "test");
5866     test_ifaces((IUnknown*)node, text_iids);
5867     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
5868     test_text_length((IUnknown*)node, 4);
5869
5870     V_VT(&var) = VT_NULL;
5871     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
5872     IHTMLDOMNode_Release(node);
5873
5874     node = test_create_text(doc, "insert ");
5875
5876     V_VT(&var) = VT_DISPATCH;
5877     V_DISPATCH(&var) = (IDispatch*)node2;
5878     node3 = test_node_insertbefore((IUnknown*)body, node, &var);
5879     IHTMLDOMNode_Release(node);
5880     IHTMLDOMNode_Release(node2);
5881     IHTMLDOMNode_Release(node3);
5882
5883     test_elem_innertext(body, "insert test");
5884     test_elem_innerhtml((IUnknown*)body, "insert test");
5885
5886     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
5887     if(hres == S_OK)
5888     {
5889         str = a2bstr("testing");
5890         hres = IHTMLDocument5_createComment(doc5, str, &comment);
5891         SysFreeString(str);
5892         ok(hres == S_OK, "createComment failed: %08x\n", hres);
5893         if(hres == S_OK)
5894         {
5895             type = get_node_type((IUnknown*)comment);
5896             ok(type == 8, "type=%d, expected 8\n", type);
5897
5898             test_node_get_value_str((IUnknown*)comment, "testing");
5899
5900             IHTMLDOMNode_Release(comment);
5901         }
5902
5903         IHTMLDocument5_Release(doc5);
5904     }
5905
5906     IHTMLElement_Release(body);
5907 }
5908
5909 static void test_exec(IUnknown *unk, const GUID *grpid, DWORD cmdid, VARIANT *in, VARIANT *out)
5910 {
5911     IOleCommandTarget *cmdtrg;
5912     HRESULT hres;
5913
5914     hres = IHTMLTxtRange_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
5915     ok(hres == S_OK, "Could not get IOleCommandTarget interface: %08x\n", hres);
5916
5917     hres = IOleCommandTarget_Exec(cmdtrg, grpid, cmdid, 0, in, out);
5918     ok(hres == S_OK, "Exec failed: %08x\n", hres);
5919
5920     IOleCommandTarget_Release(cmdtrg);
5921 }
5922
5923 static void test_indent(IHTMLDocument2 *doc)
5924 {
5925     IHTMLElementCollection *col;
5926     IHTMLTxtRange *range;
5927     HRESULT hres;
5928
5929     static const elem_type_t all_types[] = {
5930         ET_HTML,
5931         ET_HEAD,
5932         ET_TITLE,
5933         ET_BODY,
5934         ET_BR,
5935         ET_A,
5936     };
5937
5938     static const elem_type_t indent_types[] = {
5939         ET_HTML,
5940         ET_HEAD,
5941         ET_TITLE,
5942         ET_BODY,
5943         ET_BLOCKQUOTE,
5944         ET_P,
5945         ET_BR,
5946         ET_A,
5947     };
5948
5949     hres = IHTMLDocument2_get_all(doc, &col);
5950     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5951     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5952     IHTMLElementCollection_Release(col);
5953
5954     range = test_create_body_range(doc);
5955     test_exec((IUnknown*)range, &CGID_MSHTML, IDM_INDENT, NULL, NULL);
5956     IHTMLTxtRange_Release(range);
5957
5958     hres = IHTMLDocument2_get_all(doc, &col);
5959     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5960     test_elem_collection((IUnknown*)col, indent_types, sizeof(indent_types)/sizeof(indent_types[0]));
5961     IHTMLElementCollection_Release(col);
5962 }
5963
5964 static void test_cond_comment(IHTMLDocument2 *doc)
5965 {
5966     IHTMLElementCollection *col;
5967     HRESULT hres;
5968
5969     static const elem_type_t all_types[] = {
5970         ET_HTML,
5971         ET_HEAD,
5972         ET_TITLE,
5973         ET_BODY,
5974         ET_BR
5975     };
5976
5977     hres = IHTMLDocument2_get_all(doc, &col);
5978     ok(hres == S_OK, "get_all failed: %08x\n", hres);
5979     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
5980     IHTMLElementCollection_Release(col);
5981 }
5982
5983 static void test_frame(IDispatch *disp, const char *exp_id)
5984 {
5985     IHTMLWindow2 *frame2, *parent, *top;
5986     IHTMLDocument2 *parent_doc, *top_doc;
5987     IHTMLWindow4 *frame;
5988     IHTMLFrameBase *frame_elem;
5989     HRESULT hres;
5990
5991     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow4, (void**)&frame);
5992     ok(hres == S_OK, "Could not get IHTMLWindow4 interface: 0x%08x\n", hres);
5993     if(FAILED(hres))
5994         return;
5995
5996     hres = IHTMLWindow4_get_frameElement(frame, &frame_elem);
5997     ok(hres == S_OK, "IHTMLWindow4_get_frameElement failed: 0x%08x\n", hres);
5998     IHTMLWindow4_Release(frame);
5999     if(FAILED(hres))
6000         return;
6001
6002     test_elem_type((IUnknown*)frame_elem, ET_FRAME);
6003     test_frame_doc((IUnknown*)frame_elem, FALSE);
6004     test_elem_id((IUnknown*)frame_elem, exp_id);
6005     IHTMLElement_Release(frame_elem);
6006
6007     hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow2, (void**)&frame2);
6008     ok(hres == S_OK, "Could not get IHTMLWindow2 interface: 0x%08x\n", hres);
6009     if(FAILED(hres))
6010         return;
6011
6012     hres = IHTMLWindow2_get_parent(frame2, &parent);
6013     ok(hres == S_OK, "IHTMLWindow2_get_parent failed: 0x%08x\n", hres);
6014     if(FAILED(hres)){
6015         IHTMLWindow2_Release(frame2);
6016         return;
6017     }
6018
6019     hres = IHTMLWindow2_get_document(parent, &parent_doc);
6020     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
6021     IHTMLWindow2_Release(parent);
6022     if(FAILED(hres)){
6023         IHTMLWindow2_Release(frame2);
6024         return;
6025     }
6026
6027     test_doc_title(parent_doc, "frameset test");
6028     IHTMLDocument2_Release(parent_doc);
6029
6030     /* test get_top */
6031     hres = IHTMLWindow2_get_top(frame2, &top);
6032     ok(hres == S_OK, "IHTMLWindow2_get_top failed: 0x%08x\n", hres);
6033     IHTMLWindow2_Release(frame2);
6034     if(FAILED(hres))
6035         return;
6036
6037     hres = IHTMLWindow2_get_document(top, &top_doc);
6038     ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
6039     IHTMLWindow2_Release(top);
6040     if(FAILED(hres))
6041         return;
6042
6043     test_doc_title(top_doc, "frameset test");
6044     IHTMLDocument2_Release(top_doc);
6045 }
6046
6047 static void test_frameset(IHTMLDocument2 *doc)
6048 {
6049     IHTMLWindow2 *window;
6050     IHTMLFramesCollection2 *frames;
6051     IHTMLElement *elem;
6052     IHTMLFrameBase *fbase;
6053     LONG length;
6054     VARIANT index_var, result_var;
6055     BSTR str;
6056     HRESULT hres;
6057
6058     window = get_doc_window(doc);
6059
6060     /* test using IHTMLFramesCollection object */
6061
6062     hres = IHTMLWindow2_get_frames(window, &frames);
6063     ok(hres == S_OK, "IHTMLWindow2_get_frames failed: 0x%08x\n", hres);
6064     IHTMLWindow2_Release(window);
6065     if(FAILED(hres))
6066         return;
6067
6068     /* test result length */
6069     hres = IHTMLFramesCollection2_get_length(frames, &length);
6070     ok(hres == S_OK, "IHTMLFramesCollection2_get_length failed: 0x%08x\n", hres);
6071     ok(length == 3, "IHTMLFramesCollection2_get_length should have been 3, was: %d\n", length);
6072
6073     /* test first frame */
6074     V_VT(&index_var) = VT_I4;
6075     V_I4(&index_var) = 0;
6076     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6077     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
6078     if(SUCCEEDED(hres)) {
6079         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6080         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
6081     }
6082     VariantClear(&result_var);
6083
6084     /* test second frame */
6085     V_I4(&index_var) = 1;
6086     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6087     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
6088     if(SUCCEEDED(hres)) {
6089         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6090         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
6091     }
6092     VariantClear(&result_var);
6093
6094     /* fail on next frame */
6095     V_I4(&index_var) = 3;
6096     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6097     ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLFramesCollection2_item should have"
6098            "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
6099     VariantClear(&result_var);
6100
6101     /* string argument (element id lookup) */
6102     V_VT(&index_var) = VT_BSTR;
6103     V_BSTR(&index_var) = a2bstr("fr1");
6104     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6105     ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
6106     if(SUCCEEDED(hres)) {
6107         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6108         test_frame(V_DISPATCH(&result_var), "fr1");
6109     }
6110     VariantClear(&result_var);
6111     VariantClear(&index_var);
6112
6113     /* invalid argument */
6114     V_VT(&index_var) = VT_BOOL;
6115     V_BOOL(&index_var) = VARIANT_TRUE;
6116     hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
6117     ok(hres == E_INVALIDARG, "IHTMLFramesCollection2_item should have"
6118            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
6119     VariantClear(&result_var);
6120
6121     IHTMLFramesCollection2_Release(frames);
6122
6123     /* test using IHTMLWindow2 inheritance */
6124
6125     /* test result length */
6126     hres = IHTMLWindow2_get_length(window, &length);
6127     ok(hres == S_OK, "IHTMLWindow2_get_length failed: 0x%08x\n", hres);
6128     ok(length == 3, "IHTMLWindow2_get_length should have been 3, was: %d\n", length);
6129
6130     /* test first frame */
6131     V_VT(&index_var) = VT_I4;
6132     V_I4(&index_var) = 0;
6133     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6134     ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
6135     if(SUCCEEDED(hres)) {
6136         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6137         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
6138     }
6139     VariantClear(&result_var);
6140
6141     /* test second frame */
6142     V_I4(&index_var) = 1;
6143     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6144     ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
6145     if(SUCCEEDED(hres)) {
6146         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6147         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
6148     }
6149     VariantClear(&result_var);
6150
6151     /* fail on next frame */
6152     V_I4(&index_var) = 3;
6153     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6154     ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLWindow2_item should have"
6155            "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
6156     VariantClear(&result_var);
6157
6158     /* string argument (element id lookup) */
6159     V_VT(&index_var) = VT_BSTR;
6160     V_BSTR(&index_var) = a2bstr("fr2");
6161     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6162     ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
6163     if(SUCCEEDED(hres)) {
6164         ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
6165         test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
6166     }
6167     VariantClear(&result_var);
6168     VariantClear(&index_var);
6169
6170     /* invalid argument */
6171     V_VT(&index_var) = VT_BOOL;
6172     V_BOOL(&index_var) = VARIANT_TRUE;
6173     hres = IHTMLWindow2_item(window, &index_var, &result_var);
6174     ok(hres == E_INVALIDARG, "IHTMLWindow2_item should have"
6175            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
6176     VariantClear(&result_var);
6177
6178     /* getElementById with node name attributes */
6179     elem = get_doc_elem_by_id(doc, "nm1");
6180     test_elem_id((IUnknown*)elem, "fr1");
6181
6182     /* get/put scrolling */
6183     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
6184     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
6185
6186     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
6187     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
6188     ok(!strcmp_wa(str, "auto"), "get_scrolling should have given 'auto', gave: %s\n", wine_dbgstr_w(str));
6189     SysFreeString(str);
6190
6191     str = a2bstr("no");
6192     hres = IHTMLFrameBase_put_scrolling(fbase, str);
6193     ok(hres == S_OK, "IHTMLFrameBase_put_scrolling failed: 0x%08x\n", hres);
6194     SysFreeString(str);
6195
6196     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
6197     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
6198     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
6199     SysFreeString(str);
6200
6201     str = a2bstr("junk");
6202     hres = IHTMLFrameBase_put_scrolling(fbase, str);
6203     ok(hres == E_INVALIDARG, "IHTMLFrameBase_put_scrolling should have failed "
6204             "with E_INVALIDARG, instead: 0x%08x\n", hres);
6205     SysFreeString(str);
6206
6207     hres = IHTMLFrameBase_get_scrolling(fbase, &str);
6208     ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
6209     ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
6210     SysFreeString(str);
6211
6212     /* get_name */
6213     hres = IHTMLFrameBase_get_name(fbase, &str);
6214     ok(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres);
6215     ok(!strcmp_wa(str, "nm1"), "get_name should have given 'nm1', gave: %s\n", wine_dbgstr_w(str));
6216     SysFreeString(str);
6217
6218     IHTMLFrameBase_Release(fbase);
6219     IHTMLElement_Release(elem);
6220
6221     /* get_name with no name attr */
6222     elem = get_doc_elem_by_id(doc, "fr3");
6223     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
6224     ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
6225
6226     hres = IHTMLFrameBase_get_name(fbase, &str);
6227     ok(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres);
6228     ok(str == NULL, "get_name should have given 'null', gave: %s\n", wine_dbgstr_w(str));
6229     SysFreeString(str);
6230
6231     IHTMLFrameBase_Release(fbase);
6232     IHTMLElement_Release(elem);
6233 }
6234
6235 static IHTMLDocument2 *notif_doc;
6236 static BOOL doc_complete;
6237
6238 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
6239         REFIID riid, void**ppv)
6240 {
6241     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
6242         *ppv = iface;
6243         return S_OK;
6244     }
6245
6246     ok(0, "unexpected call\n");
6247     return E_NOINTERFACE;
6248 }
6249
6250 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
6251 {
6252     return 2;
6253 }
6254
6255 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
6256 {
6257     return 1;
6258 }
6259
6260 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
6261 {
6262     if(dispID == DISPID_READYSTATE){
6263         BSTR state;
6264         HRESULT hres;
6265
6266         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
6267         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
6268
6269         if(!strcmp_wa(state, "complete"))
6270             doc_complete = TRUE;
6271
6272         SysFreeString(state);
6273     }
6274
6275     return S_OK;
6276 }
6277
6278 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
6279 {
6280     ok(0, "unexpected call\n");
6281     return E_NOTIMPL;
6282 }
6283
6284 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
6285     PropertyNotifySink_QueryInterface,
6286     PropertyNotifySink_AddRef,
6287     PropertyNotifySink_Release,
6288     PropertyNotifySink_OnChanged,
6289     PropertyNotifySink_OnRequestEdit
6290 };
6291
6292 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
6293
6294 static IHTMLDocument2 *create_doc_with_string(const char *str)
6295 {
6296     IPersistStreamInit *init;
6297     IStream *stream;
6298     IHTMLDocument2 *doc;
6299     HGLOBAL mem;
6300     SIZE_T len;
6301
6302     notif_doc = doc = create_document();
6303     if(!doc)
6304         return NULL;
6305
6306     doc_complete = FALSE;
6307     len = strlen(str);
6308     mem = GlobalAlloc(0, len);
6309     memcpy(mem, str, len);
6310     CreateStreamOnHGlobal(mem, TRUE, &stream);
6311
6312     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
6313
6314     IPersistStreamInit_Load(init, stream);
6315     IPersistStreamInit_Release(init);
6316     IStream_Release(stream);
6317
6318     return doc;
6319 }
6320
6321 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
6322 {
6323     IConnectionPointContainer *container;
6324     IConnectionPoint *cp;
6325     DWORD cookie;
6326     HRESULT hres;
6327
6328     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
6329     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
6330
6331     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
6332     IConnectionPointContainer_Release(container);
6333     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
6334
6335     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
6336     IConnectionPoint_Release(cp);
6337     ok(hres == S_OK, "Advise failed: %08x\n", hres);
6338 }
6339
6340 typedef void (*domtest_t)(IHTMLDocument2*);
6341
6342 static void run_domtest(const char *str, domtest_t test)
6343 {
6344     IHTMLDocument2 *doc;
6345     ULONG ref;
6346     MSG msg;
6347
6348     doc = create_doc_with_string(str);
6349     if(!doc)
6350         return;
6351
6352     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
6353
6354     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
6355         TranslateMessage(&msg);
6356         DispatchMessage(&msg);
6357     }
6358
6359     test(doc);
6360
6361     ref = IHTMLDocument2_Release(doc);
6362     ok(!ref ||
6363        ref == 1, /* Vista */
6364        "ref = %d\n", ref);
6365 }
6366
6367 START_TEST(dom)
6368 {
6369     CoInitialize(NULL);
6370
6371     run_domtest(doc_str1, test_doc_elem);
6372     run_domtest(doc_str1, test_get_set_attr);
6373     run_domtest(range_test_str, test_txtrange);
6374     run_domtest(range_test2_str, test_txtrange2);
6375     if (winetest_interactive || ! is_ie_hardened()) {
6376         run_domtest(elem_test_str, test_elems);
6377     }else {
6378         skip("IE running in Enhanced Security Configuration\n");
6379     }
6380     run_domtest(elem_test2_str, test_elems2);
6381     run_domtest(doc_blank, test_create_elems);
6382     run_domtest(doc_blank, test_defaults);
6383     run_domtest(indent_test_str, test_indent);
6384     run_domtest(cond_comment_str, test_cond_comment);
6385     run_domtest(frameset_str, test_frameset);
6386
6387     CoUninitialize();
6388 }