From b0abb6972043d4240b763603075f6979a69b88ef Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Tue, 3 Jul 2012 17:23:00 +0200 Subject: Make it possible to sort the HTML tables OTP-9896 Introduce java scripts in the web pages to enable sorting of table elements. --- lib/common_test/src/ct_logs.erl | 286 ++++++++++++++++++++++++++++++---------- 1 file changed, 218 insertions(+), 68 deletions(-) (limited to 'lib/common_test/src/ct_logs.erl') diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index 1ccbdc3718..fc4ede1e32 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -35,8 +35,9 @@ -export([add_external_logs/1,add_link/3]). -export([make_last_run_index/0]). -export([make_all_suites_index/1,make_all_runs_index/1]). --export([get_ts_html_wrapper/3]). --export([xhtml/2, locate_default_css_file/0, make_relative/1]). +-export([get_ts_html_wrapper/4]). +-export([xhtml/2, locate_priv_file/1, make_relative/1]). +-export([insert_javascript/1]). %% Logging stuff directly from testcase -export([tc_log/3,tc_log/4,tc_log_async/3,tc_print/3,tc_pal/3,ct_log/3, @@ -56,7 +57,6 @@ -define(all_runs_name, "all_runs.html"). -define(index_name, "index.html"). -define(totals_name, "totals.info"). --define(css_default, "ct_default.css"). -define(table_color1,"#ADD8E6"). -define(table_color2,"#E4F0FE"). @@ -371,7 +371,7 @@ tc_log_async(Category,Format,Args) -> %%% @doc Console printout from a testcase. %%% %%%

This function is called by ct when printing -%%% stuff a testcase on the user console.

+%%% stuff from a testcase on the user console.

tc_print(Category,Format,Args) -> Head = get_heading(Category), io:format(user, lists:concat([Head,Format,"\n\n"]), Args), @@ -502,26 +502,27 @@ logger(Parent,Mode) -> %% dir) so logs are independent of Common Test installation {ok,Cwd} = file:get_cwd(), CTPath = code:lib_dir(common_test), - CSSFileSrc = filename:join(filename:join(CTPath, "priv"), - ?css_default), - CSSFileDestTop = filename:join(Cwd, ?css_default), - CSSFileDestRun = filename:join(AbsDir, ?css_default), - case file:copy(CSSFileSrc, CSSFileDestTop) of - {error,Reason0} -> + PrivFiles = [?css_default,?jquery_script,?tablesorter_script], + PrivFilesSrc = [filename:join(filename:join(CTPath, "priv"), F) || + F <- PrivFiles], + PrivFilesDestTop = [filename:join(Cwd, F) || F <- PrivFiles], + PrivFilesDestRun = [filename:join(AbsDir, F) || F <- PrivFiles], + case copy_priv_files(PrivFilesSrc, PrivFilesDestTop) of + {error,Src1,Dest1,Reason1} -> io:format(user, "ERROR! "++ - "CSS file ~p could not be copied to ~p. "++ - "Reason: ~p~n", - [CSSFileSrc,CSSFileDestTop,Reason0]), - exit({css_file_error,CSSFileDestTop}); - _ -> - case file:copy(CSSFileSrc, CSSFileDestRun) of - {error,Reason1} -> + "Priv file ~p could not be copied to ~p. "++ + "Reason: ~p~n", + [Src1,Dest1,Reason1]), + exit({priv_file_error,Dest1}); + ok -> + case copy_priv_files(PrivFilesSrc, PrivFilesDestRun) of + {error,Src2,Dest2,Reason2} -> io:format(user, "ERROR! "++ - "CSS file ~p could not be copied to ~p. "++ - "Reason: ~p~n", - [CSSFileSrc,CSSFileDestRun,Reason1]), - exit({css_file_error,CSSFileDestRun}); - _ -> + "Priv file ~p could not be copied to ~p. "++ + "Reason: ~p~n", + [Src2,Dest2,Reason2]), + exit({priv_file_error,Dest2}); + ok -> ok end end @@ -549,6 +550,16 @@ logger(Parent,Mode) -> tc_groupleaders=[], async_print_jobs=[]}). +copy_priv_files([SrcF | SrcFs], [DestF | DestFs]) -> + case file:copy(SrcF, DestF) of + {error,Reason} -> + {error,SrcF,DestF,Reason}; + _ -> + copy_priv_files(SrcFs, DestFs) + end; +copy_priv_files([], []) -> + ok. + logger_loop(State) -> receive {log,SyncOrAsync,Pid,GL,List} -> @@ -770,7 +781,7 @@ set_evmgr_gl(GL) -> open_ctlog() -> {ok,Fd} = file:open(?ct_log_name,[write]), - io:format(Fd, header("Common Test Framework Log"), []), + io:format(Fd, header("Common Test Framework Log", {[],[1,2],[]}), []), case file:consult(ct_run:variables_file_name("../")) of {ok,Vars} -> io:format(Fd, config_table(Vars), []); @@ -1080,14 +1091,14 @@ total_row(Success, Fail, UserSkip, AutoSkip, NotBuilt, All) -> integer_to_list(UserSkip),integer_to_list(AutoSkip)} end, [xhtml("\n", - ["\n"]), + ["\n\n\n"]), "Total\n", Label, TimestampCell, "",integer_to_list(Success),"\n", "",integer_to_list(Fail),"\n", "",integer_to_list(AllSkip), " (",UserSkipStr,"/",AutoSkipStr,")\n", "",integer_to_list(NotBuilt),"\n", - AllInfo, "\n"]. + AllInfo, "\n\n"]. not_built(_BaseName,_LogDir,_All,[]) -> 0; @@ -1144,10 +1155,12 @@ index_header(Label, StartTime) -> Head = case Label of undefined -> - header("Test Results", format_time(StartTime)); + header("Test Results", format_time(StartTime), + {[],[1],[2,3,4,5]}); _ -> header("Test Results for '" ++ Label ++ "'", - format_time(StartTime)) + format_time(StartTime), + {[],[1],[2,3,4,5]}) end, [Head | ["
\n", @@ -1159,15 +1172,17 @@ index_header(Label, StartTime) -> "\">COMMON TEST FRAMEWORK LOG\n"]), xhtml("
\n", "


\n"), xhtml(["\n"], "
\n"), + "bgcolor=\"",?table_color3,"\">\n"], + ["
\n", + "\n\n"]), "\n", xhtml(["\n"], "\n"), "\n", "\n" - "\n" - "\n"]]. + "\n", + xhtml("", "\n\n\n")]]. all_suites_index_header() -> {ok,Cwd} = file:get_cwd(), @@ -1180,12 +1195,14 @@ all_suites_index_header(IndexDir) -> AllRunsLink = xhtml(["",AllRuns,"\n"], [""]), - [header("Test Results") | + [header("Test Results", {[3],[1,2,8,9,10],[4,5,6,7]}) | ["
\n", AllRunsLink, xhtml("

\n", "

\n"), xhtml(["
Test Name_Ok" "_OkFailedSkipped", xhtml("
", "
"), "(User/Auto)
Missing", xhtml("
", "
"), "Suites
Missing", xhtml("
", "
"), "Suites
\n"], "
\n"), + "bgcolor=\"",?table_color2,"\">\n"], + ["
\n", + "\n\n"]), "\n", "\n", "\n", @@ -1198,7 +1215,7 @@ all_suites_index_header(IndexDir) -> "\n", "\n", "\n", - "\n"]]. + xhtml("", "\n\n\n")]]. all_runs_header() -> {ok,Cwd} = file:get_cwd(), @@ -1210,10 +1227,12 @@ all_runs_header() -> "TEST INDEX PAGE\n"]), xhtml("
\n", "

\n")], - [header(Title) | + [header(Title, {[1],[2,3,5],[4,6,7,8,9,10]}) | ["
\n", IxLink, xhtml(["
Test NameLabelTest Run StartedNodeCT LogOld Runs
\n"], "
\n"), + "bgcolor=\"",?table_color1,"\">\n"], + ["
\n", + "\n\n"]), "\n" "\n" "\n" @@ -1225,23 +1244,29 @@ all_runs_header() -> "\n"), "\n" "\n" - "\n" - "\n"]]. + "\n", + xhtml("", "\n\n\n")]]. -header(Title) -> - header1(Title, ""). -header(Title, SubTitle) -> - header1(Title, SubTitle). +header(Title, TableCols) -> + header1(Title, "", TableCols). +header(Title, SubTitle, TableCols) -> + header1(Title, SubTitle, TableCols). -header1(Title, SubTitle) -> +header1(Title, SubTitle, TableCols) -> SubTitleHTML = if SubTitle =/= "" -> ["
\n", "

" ++ SubTitle ++ "

\n", xhtml("
\n
\n", "\n
\n")]; - true -> xhtml("
\n", "
\n") + true -> xhtml("
", "
") end, CSSFile = xhtml(fun() -> "" end, - fun() -> make_relative(locate_default_css_file()) end), + fun() -> make_relative(locate_priv_file(?css_default)) end), + JQueryFile = + xhtml(fun() -> "" end, + fun() -> make_relative(locate_priv_file(?jquery_script)) end), + TableSorterFile = + xhtml(fun() -> "" end, + fun() -> make_relative(locate_priv_file(?tablesorter_script)) end), [xhtml(["\n", "\n"], [" "" ++ Title ++ " " ++ SubTitle ++ "\n", "\n", xhtml("", - [""]), + ["\n"]), + xhtml("", + ["\n"]), + xhtml("", + ["\n"]), + xhtml(fun() -> "" end, + fun() -> insert_javascript({tablesorter,?sortable_table_name, + TableCols}) + end), "\n", body_tag(), "
\n", @@ -1264,6 +1299,10 @@ index_footer() -> ["
HistoryNodeLabelOkFailedSkipped
(User/Auto)
Missing
Suites
Missing
Suites
\n" "
\n" | footer()]. +all_runs_index_footer() -> + ["\n\n" + "\n" | footer()]. + footer() -> ["
\n", xhtml("

\n
\n", "

\n"), @@ -1275,7 +1314,8 @@ footer() -> xhtml("
\n", "
\n"), xhtml("

\n", "\n"), "
\n" - "\n"]. + "\n" + "\n"]. body_tag() -> @@ -1291,7 +1331,7 @@ current_time() -> format_time({{Y, Mon, D}, {H, Min, S}}) -> Weekday = weekday(calendar:day_of_the_week(Y, Mon, D)), - lists:flatten(io_lib:format("~s ~s ~p ~w ~2.2.0w:~2.2.0w:~2.2.0w", + lists:flatten(io_lib:format("~s ~s ~2.2.0w ~w ~2.2.0w:~2.2.0w:~2.2.0w", [Weekday, month(Mon), D, Y, H, Min, S])). weekday(1) -> "Mon"; @@ -1417,8 +1457,12 @@ config_table_header() -> [ xhtml(["

Configuration

\n" "CONFIGURATION\n
\n"), - "\n"]. + ["

CONFIGURATION

\n", + "
KeyValue
\n", + "\n"]), + "\n", + xhtml("", "\n\n") + ]. config_table1([{Key,Value}|Vars]) -> [xhtml(["\n", @@ -1428,7 +1472,7 @@ config_table1([{Key,Value}|Vars]) -> "\n\n"]) | config_table1(Vars)]; config_table1([]) -> - ["
KeyValue
", atom_to_list(Key), "", io_lib:format("~p",[Value]), "
\n"]. + ["\n\n"]. make_all_runs_index(When) -> @@ -1442,7 +1486,8 @@ make_all_runs_index(When) -> DirsSorted = (catch sort_all_runs(Dirs)), Header = all_runs_header(), Index = [runentry(Dir) || Dir <- DirsSorted], - Result = file:write_file(AbsName,Header++Index++index_footer()), + Result = file:write_file(AbsName,Header++Index++ + all_runs_index_footer()), if When == start -> ok; true -> io:put_chars("done\n") end, @@ -2078,34 +2123,34 @@ basic_html() -> end. %%%----------------------------------------------------------------- -%%% @spec locate_default_css_file() -> CSSFile +%%% @spec locate_priv_file(FileName) -> PrivFile %%% %%% @doc %%% -locate_default_css_file() -> +locate_priv_file(FileName) -> {ok,CWD} = file:get_cwd(), - CSSFileInCwd = filename:join(CWD, ?css_default), - case filelib:is_file(CSSFileInCwd) of + PrivFileInCwd = filename:join(CWD, FileName), + case filelib:is_file(PrivFileInCwd) of true -> - CSSFileInCwd; + PrivFileInCwd; false -> - CSSResultFile = + PrivResultFile = case {whereis(?MODULE),self()} of {Self,Self} -> %% executed on the ct_logs process - filename:join(get(ct_run_dir), ?css_default); + filename:join(get(ct_run_dir), FileName); _ -> %% executed on other process than ct_logs {ok,RunDir} = get_log_dir(true), - filename:join(RunDir, ?css_default) + filename:join(RunDir, FileName) end, - case filelib:is_file(CSSResultFile) of + case filelib:is_file(PrivResultFile) of true -> - CSSResultFile; + PrivResultFile; false -> %% last resort, try use css file in CT installation CTPath = code:lib_dir(common_test), - filename:join(filename:join(CTPath, "priv"), ?css_default) + filename:join(filename:join(CTPath, "priv"), FileName) end end. @@ -2144,7 +2189,7 @@ make_relative1(DirTs, CwdTs) -> %%% %%% @doc %%% -get_ts_html_wrapper(TestName, PrintLabel, Cwd) -> +get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols) -> TestName1 = if is_list(TestName) -> lists:flatten(TestName); true -> @@ -2204,17 +2249,36 @@ get_ts_html_wrapper(TestName, PrintLabel, Cwd) -> "Open Telecom Platform
\n", "Updated: ", current_time(), "", "
\n\n"], - CSSFile = xhtml(fun() -> "" end, - fun() -> make_relative(locate_default_css_file(), Cwd) end), + CSSFile = + xhtml(fun() -> "" end, + fun() -> make_relative(locate_priv_file(?css_default), + Cwd) + end), + JQueryFile = + xhtml(fun() -> "" end, + fun() -> make_relative(locate_priv_file(?jquery_script), + Cwd) + end), + TableSorterFile = + xhtml(fun() -> "" end, + fun() -> make_relative(locate_priv_file(?tablesorter_script), + Cwd) + end), + TableSorterScript = + xhtml(fun() -> "" end, + fun() -> insert_javascript({tablesorter, + ?sortable_table_name, + TableCols}) end), {xhtml, ["\n", "\n", "\n", TestName1, "\n", "\n", - "", - "\n","\n", - LabelStr, "\n"], + "\n", + "\n", + "\n"] ++ + TableSorterScript ++ ["\n","\n", LabelStr, "\n"], ["
\n

\n", "Test run history\n | ", @@ -2222,3 +2286,89 @@ get_ts_html_wrapper(TestName, PrintLabel, Cwd) -> "\">Top level test index\n\n

\n", Copyright,"
\n\n\n"]} end. + +insert_javascript({tablesorter,_TableName,undefined}) -> + []; + +insert_javascript({tablesorter,TableName, + {DateCols,TextCols,ValCols}}) -> + Headers = + lists:flatten( + lists:sort( + lists:flatmap(fun({Sorter,Cols}) -> + [lists:flatten( + io_lib:format(" ~w: " + "{ sorter: '~s' },\n", + [Col-1,Sorter])) || Col<-Cols] + end, [{"CTDateSorter",DateCols}, + {"CTTextSorter",TextCols}, + {"CTValSorter",ValCols}]))), + Headers1 = string:substr(Headers, 1, length(Headers)-2), + + ["\n"]. -- cgit v1.2.3